数组中查找两个不同的数字

代码要求:

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

思路:

1.两个相同的数字异或为0。

2.将两个不同的数字分到不同的组分别进行异或。

3.怎样将这两个不同的数字分开:当我们尝试去异或不同的数字的时候例如:3 对应的二进制 011 而4对应的二进制100,异或得 111 再比如 4 和5(101) 得到为001;
这样我们就可以发现规律:当不同的数字进行异或操作的时候那么异或的值至少含有一个1 那么这个1 一定是由对应位置的1和0的得到的。

4.那么此时我们算是找到不同点:所以我们要先去找到这两个数字异或得到那么1的位置然后判断其值作为区分为不同的两个数组的条件。

函数实现:

void Find(const int* a, int sz, int* x, int* y) 
{
	assert(a);
    int ret= 0;// 保存数组间异或的结果
	int pos = 0;//用来保存寻找到异或为1的位置
	int i = 0; 
	int num1 = 0;//用来保两个不同的数字
	int num2 = 0;
//将数组的内容进行异或,结果保留到ret内
	for ( i = 0; i < sz; i++) 
	{
		ret^= a[i];
	}

//去查找ret值为1的位置保留到pos内
	while (!((ret>>pos) & 1) )
	{
	pos++;
	}
	
// 将数组a内的每个值的二进制位右移pos位进而判断这个值是1/0,这样就可以将数组的元素分为两个部分分别进行异或,值保留到num1 和num2 内
	for (i = 0; i < sz; i++) {
		if (((a[i] >> pos) & 1) == 1)
		{
			num1 ^= a[i];
		}
		else if(((a[i] >> pos) & 1) == 0)
		{
			num2 ^= a[i];
		}
	}
//将两个不同的数字存入到x,y内
	*x = num1;
	*y = num2;
	
	return;
}

测试:


int main() 
{
	int a[10] = { 1,2,3,4,8,6,1,2,3,4 };
	int sz = sizeof(a) / sizeof(a[0]);
	int x = 0;
	int y = 0;
	Find(a,sz,&x,&y);
	printf("%d %d", x, y);

	return 0;
}

测试结果:

数组中查找两个不同的数字_第1张图片

你可能感兴趣的:(c语言)