1. 程式人生 > >整型數組裡只出現一次的數字--[c語言筆試題]

整型數組裡只出現一次的數字--[c語言筆試題]

找出陣列內只出現一次的數字,是一系列的筆試題,來考察大家對位運算的掌握,下面我們從最簡單的開始來看看吧!

一、題目:一個整型數組裡只有一個數字出現了一次,其餘數字都出現了兩次,請寫程式找出出現了一次的數字。
  如:{1,2,1,2,3},找出1

看到這個題目時,我們容易想到異或運算的性質。異或運算相同為0,相異為1,則:

a^a = 0; (1)

0^a = a; (2)

a^b^a = b; (3)

通過以上前兩式,以上數組裡兩兩相同的異或結果為0,0在與只出現一次的那個數字異或就會得到這個數字,你也可以通過3

式想,1^2^1 = 2, 2^2 = 0,0^3 = 3,還是找到了我們想要的數。不管怎麼想,我們都得到統一的思路:將數組裡面所有的數字異或一遍,最終得到的那個數字就是隻出現一次的數。

[c語言程式碼]:

int FindAppearOnce(int arr[], int len)
{
	int i = 0;
	int ret = 0;
	for(i = 0; i<len; i++)
	{
		ret = arr[i]^ret;
	}
	return ret;
}

二、題目:一個整型數組裡除了兩個數字之外,其他的數字都出現了兩次,請寫程式找出這兩個只出現一次的數字。
  如:{1,2,1,2,3,4},找出3和4

有了上道題的鋪墊,我們來整理一下這道題的思路:

第一步,將陣列中所有數字異或一遍,得到的結果為兩個只出現一次的數字的異或結果

              本題為:0011(3)^(0100)4  =  0111(7)  括號內為十進位制

第二步,在第一步得到的數字的二進位制中找出第一個為1的位,通過這個位為0或為1,將陣列中的數字分為兩組。這兩個組裡出現一次的兩個數必定不在同一組,兩個相同的數字必定會被分在一個組。

             本題0111最低位就為1,將陣列中最低位為1的放在一組,為0的放在另一組,則3和4必定不在同一組,因為找出的這  個位為1,即3和4 的這一位不同。則一組為:1,1,3 二組:2,2,4

第三步,將兩個組中的所有數字分別異或,就會得到每個組中只出現一次的那個數。(思想同第一題)

             本題1^1^3 = 3,2^2^4 = 4,所以就找到了只出現了一次的兩個數。

[c語言程式碼]:

void FindAppearOnce(int arr[], int len, int* pn1, int* pn2)
{
	int num = 0;//記錄整組異或的結果,即兩個一次出現的數異或的結果
	int i = 0;
	int k = 1;

	for(i = 0; i<len; i++)  //得出整組異或的結果,即兩個一次出現的數異或的結果
	{
		num = num^arr[i];
	}

	while(num&1 != 1)    //找出異或結果中第一個為1的bit位
	{
		k++;
		num = num>>1;
	}

	for(i = 0; i<len ; i++)//將原陣列分為兩組,分別求出每組中出現一次的數字
	{
		int k_bit = (arr[i]>>(k-1)) & 1; //arr[i]第k位的值
		if(k_bit == 1)
		{
			*pn1 = *pn1^arr[i];
		}
		else
		{
			*pn2 = *pn2^arr[i];
		}
	}

}

大家實現的時候可以根據功能分幾個函式。

謝謝閱讀!!