C语言实现找单身狗

给定一组数组,eg:{1,2,3,4,5,6,1,2,3,4},请找出5和7两个数。
解题思路,首先我们可以分组,注意,5和7必须分到不同的组里,那该要怎么实现呢?我们可以考虑使用异或运算,我们可以选择让1 4 1 4 5一组,2 3 2 3 6 一组,两组异或之后分别得出5和6的二进制表示位,我们可以观察到5和6的二进制分别为101,110,我们可以看出他们的最后一位不同,所以我们可以根据这个思路寻找。
1、首先可以让数组中的全部元素进行异或运算,那么此时得到的结果就为5和6异或的结果,因为相同得元素异或之后就为0了
for (i = 0; i < k; i++)
{
ret = arr[i] ^ ret;//ret存放的是5和6异或的结果

}

2、我们让ret向后移i位,直到找到与ret做&运算为1时I的位置。
找到并记录。
3、我们再让数组中的元素和1进行&运算,如果等于1的话,那么就划分为第一组,再让第一组进行一个异或运算,此时就可以得到5的值,同理如果不等于1被划分为第二组。此时6的结果也被得出
源码如下:
void find(int arr[], int k)
{
int i = 0;
int ret = 0;
for (i = 0; i < k; i++)
{
ret = arr[i] ^ ret;//ret存放的是5和6异或的结果

	}
	int pos = 0;//记录ret移动了多少位为1
	for (i = 0; i < 32; i++)
	{
	
		if (((ret >> i) & 1) == 1)
		{
			pos = i;//如果ret进行了i次位移与1进行与运算为1,那么跳出循环,并记录i的位置
			break;
		}
	}
	int x = 0;//用来接收位移pos位后和1进行与运算等于1的所有结果
	int y = 0;
	for (i = 0; i < k; i++)
	{

		if (((arr[i] >> pos) & 1) == 1)//此时让数组中的元素也进行位移pos位操作,
		{
			x = x ^ arr[i];//没得到一次x的结果就进行异或运算,这样元素值相同的元素会变为0
		}
		else
		{
			y = y ^ arr[i];
		}


	}
	printf("%d %d", x, y);

}


int main()
{
	int arr[] = { 1, 2,3,4,5,8,1,2,3,4};
	int sz = sizeof(arr) / sizeof(arr[0]);
	find(arr, sz);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/Kirihara_Yukiho/article/details/123384769