求一组数的出现一次的数(位运算)

版权声明:Zhining https://blog.csdn.net/weixin_43214609/article/details/83547551
  • a^a=0 ; a^0=a;
  • 一个数只出现一次,可以将整个数组进行^处理,相同的会为0,直到出现一次的数^后即为它本身。
  • 有a、b两个数只出现一次,可以先将整个数组^处理,得到c,c =a^b,找出第N位不同即c的第N位一定为1,将数组分为两组,一个第N位为1,一个为0,然后分别将两个数组异或,得到a和b。

下面是代码:

//只有一个出现一次的数
int main()
{
	int arr[] = { 2, 4, 2, 5, 4, 6, 5, 8, 6 };
	int ret = arr[0];
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 1; i < sz; i++)
	{
		ret ^= arr[i];
	}
	printf("出现一次的数为:%d", ret);

	system("pause");
	return 0;
}
int find(int arr[], int sz, int *pnum1, int*pnum2)
{
	int ret = 0;
	for (int i = 1; i < sz; i++)
	{
		ret ^= arr[i];//ret为num1和num2异或的结果
	}

	int pos = 0;
	while (((ret >> pos) & 1) != 1)//找出不同的第pos位
	{
		pos++;
	}

	for (int i = 0; i < sz; i++)
	{
		if ((arr[i] >> pos) & 1 == 1)//分成两组
		{
			*pnum1 ^= arr[i];//不一样的bite位上是1的
		}
		else
		{
			*pnum2 ^= arr[i];
		}
	}
}

int main()
{
	int arr[] = { 2, 4, 2, 5, 4, 5, 8, 6 };
	int ret = arr[0];
	int sz = sizeof(arr) / sizeof(arr[0]);
	int num1 = 0, num2 = 0;
	find(arr, sz, &num1, &num2);
	printf("出现一次的数为:%d,%d", num1,num2);

	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43214609/article/details/83547551
今日推荐