整型數組裡只出現一次的數字--[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];
}
}
}
大家實現的時候可以根據功能分幾個函式。
謝謝閱讀!!