1. 程式人生 > >求一組數的出現一次的數(位運算)

求一組數的出現一次的數(位運算)

  • 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;
}