一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字,编程实现。

##题目

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
找出这两个数字,编程实现。

##思路1

通过位运算异或来将所有数进行位操作
位操作后取出异或后最低位的1当作flag
用flag异或数组里的每一个数可以将数分成两组
且每组只有一个数为出现一次,剩余均为两次出现
两组数内部进行异或运算,找出那个不一样的数

##思路2

先对数组排序
对有序数组前后比较
当前后相等,i + 2
否则打印这个数字,并且 i + 1

##代码
你可以前往[我的github][cd]下载此代码
[cd]:https://github.com/jo-qzy/git/blob/master/find_diff_num2.c

#define _CRT_SECURE_NO_WARNINGS 1

//一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
//找出这两个数字,编程实现。

#include <stdio.h>
#include <windows.h>

void sort(int arr[], int size);
void find_diff1(int arr[], int size);
void find_diff2(int arr[], int size);
void print_arr(int arr[], int size);

int main()
{
	int i = 0;
	int arr[] = { 1,5,6,8,9,2,1,6,9,2 };//不同的数字,5和8
	int size = sizeof(arr) / sizeof(arr[0]);
	printf("原数组:");
	print_arr(arr, size);
	printf("位运算实现:\n");
	find_diff1(arr, size);
	printf("排序实现:\n");
	sort(arr, size);
	printf("新数组:");
	print_arr(arr, size);
	find_diff2(arr, size);
	system("pause");
	return 0;
}

void print_arr(int arr[], int size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}

//思路1:位运算法
void find_diff1(int arr[], int size)
{
	int flag = 0;//flag作为分类两个组的依据
	int i = 0;
	int data1 = 0, data2 = 0;
	for (i = 0; i < size; i++)
	{
		flag ^= arr[i];
	}
	i = 0;
	while ((flag & 1) != 1)
	{
		flag = flag >> 1;
		i++;
	}
	flag = 1 << i;
	for (i = 0; i < size; i++)
	{
		if ((flag ^ arr[i]) & 1 == 1)
			data1 ^= arr[i];
		else
			data2 ^= arr[i];
	}
	printf("%d %d\n", data1, data2);
}

//思路2:排序法
void sort(int arr[], int size)
{
	int i = 0;
	for (i = 0; i < size - 1; i++)
	{
		int j = 0;
		for (j = 0; j < size - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				arr[j] ^= arr[j + 1];
				arr[j + 1] ^= arr[j];
				arr[j] ^= arr[j + 1];
			}
		}
	}
}

void find_diff2(int arr[], int size)
{
	printf("不同的数:");
	int i = 0;
	while (i < size - 1)
	{
		if (arr[i] == arr[i + 1])
		{
			i += 2;
		}
		else
		{
			printf("%d ",arr[i]);
			i++;
		}
	}
	printf("\n");
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值