C语言---一组数组中只有两个数字出现一次,其他数字都是成对出现的,请找出这两个数字。

啦啦啦。。。。。。。

首先我们先找出:数组中只有一个数字出现一次,其余数字都成对出现。实现的方法其时间复杂度为O(1);
使用异或:其数字的二进制位相同为0,不同为1.所有数字都异或,最后的异或结果就是那个只出现一次的数字。
下面是代码实现:
void FindDifference(int arr[],int n)
{
	int i = 0;
	int s = arr[0];
	if(n == 0 || n == 1)
	{
		return;
	}
	for(i = 1;i < n;i++)
	{
		s = s^arr[i];
	}
	if(s == 0)
	{
		printf("数组中所有的数字都是成对出现。\n");
	}
	else
	{
		printf("单独的数字是:%d\n",s);
	}
}

如果数组中有两个数字出现一次,那么。。。。。。。
我们只需要把一个数组分成两个数组,然后一个数组中有一个没有成对出现的数字,让其逐一进行异或,就可以找出只出现一次的数字。下面我们举个例子来促进理解:int[] = {1,2,3,4,1,2};
整个数组异或的结果为:3(0x011)^4(0x100)=7(0x111)(若异或结果的某一位为1,就说明那两个数字的那位是不同的);对于0x111,(从低位到高位)第一位就是1.所以就可以根据整个数组的第一位是1还是0来进行分组:
arr[0]  0x001;   第一组
arr[1]  0x010;   第二组
arr[2]  0x011;   第一组
arr[3]  0x100;   第二组
arr[4]  0x001;   第一组
arr[5]  0x010;   第二组
然后第一组和第二组分别进行异或,就可以找出不同的两个数字了。
下面是具体的代码实现:
void FindTwoNumbers(int *arr,int n)
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	int n1 = 0,n2 = 0;
	for(j = 0;j < n;j++)
	{
		printf("%d ",arr[j]);
	}
	printf("\n");
	for(i = 0;i < n;i++)
	{
		tmp ^= arr[i];
	}
	for(i = 1;i <= 32;i++)
	{
		if((tmp >> i) & 1 == 1)        
		{
			break;
		}
	}
	for(j = 0;j < n;j++)
	{
		if(((arr[j] >> i) & 1) == 0)
		{
			n1 ^= arr[j];                //在分组的同时进行异或。
		}
		else
		{
			n2 ^= arr[j];
		}
	}
	printf("只出现一次不同的两个数字是:%d,%d",n1,n2);
}

 
 
以上都是在VS2008的环境下运行的结果。

猜你喜欢

转载自blog.csdn.net/yinghuhu333333/article/details/79344840
今日推荐