剑指offer面试题40数组中只出现一次的两个数字,异或好题

/*
这个题目太精彩了。。还记得一年多以前做市赛预赛 遇到 数组中只有一个只出现一次的数字
这回是两个数字出现了一次 其余出现了两次
其实我们还是把思路往只有一个上想
全部异或一遍 得到的是这两个数字异或的结果
通过这个结果 我们可以把数组分成两部门,每个部分包括两个数字中的一个 和若干对数字。
我们看这个数字 最高位的1.。。。肯定只属于两个数中的一个。。
因为异或么。
也就是说这两个数字 只有一个数字在那个位置是1
那就根据位置n是否未1 把数组分未两半。。
然后就是最开始的问题了
*/
#include<iostream>
#include<cstdio>
using namespace std;

int FindOne(int * arr,int len)
{
	int ans=0;
	for(int i=0;i<len;++i)
		ans^=arr[i];
	return ans;
	
}

int FindFirstbit1(int num)//这个函数找到最右边的1的位置 从0开始计数
{
	int index=0;
	while((num&1)==0)//这里一定要注意! &的优先级低于==!!! 挺多次这里犯错了 要加括号!
	{
		index++;
		num=num>>1;
	}
	return index;
}

bool isbit1(int num,int index)
{
	num=num>>index;
	return num&1;

}
void FindNumbersAppearOnce(int * arr,int len)
{
	int tmp=0;
	for(int i=0;i<len;++i) tmp^=arr[i];
	int n=FindFirstbit1(tmp);
	int num1=0,num2=0;
	for(int i=0;i<len;++i)
	{
		if(isbit1(arr[i],n))
		num1^=arr[i];
		else
		num2^=arr[i];
	}
	printf("%d %d\n",num1,num2);
}
	
int main()
{
	int arr[]={2,4,3,6,3,2,5,5};
	int len=sizeof arr/sizeof *arr;
	FindNumbersAppearOnce(arr,len);
	return 0;
}	

你可能感兴趣的:(剑指offer面试题40数组中只出现一次的两个数字,异或好题)