首先來看題目要求:
在乙個陣列中除兩個數字只出現1次外,其它數字都出現了2次, 要求盡快找出這兩個數字。
考慮下這個題目的簡化版——陣列中除乙個數字只出現1次外,其它數字都成對出現,要求盡快找出這個數字。這個題目在之前的《
位操作基礎篇之位操作全面總結
》中的「位操作趣味應用」中就已經給出解答了。根據異或運算的特點,直接異或一次就可以找出這個數字。
現在陣列中有兩個數字只出現1次,直接異或一次只能得到這兩個數字的異或結果,但光從這個結果肯定無法得到這個兩個數字。因此我們來分析下簡化版中「異或」解法的關鍵點,這個關鍵點也相當明顯——陣列只能有乙個數字出現1次。
設題目中這兩個只出現1次的數字分別為a和b,如果能將a,b分開到二個陣列中,那顯然符合「異或」解法的關鍵點了。因此這個題目的關鍵點就是將a,
b分開到二個陣列中。由於a,b肯定是不相等的,因此在二進位製上必定有一位是不同的。根據這一位是0還是1可以將a,b分開到a組和b組。而這個陣列中其它數字要麼就屬於a組,要麼就屬於b組。再對a組和b組分別執行「異或」解法就可以得到a,b了。而要判斷a,b在哪一位上不相同,只要根據a異或b的結果就可以知道了,這個結果在二進位製上為1的位都說明a,b在這一位上是不相同的。
比如int a =
整個陣列異或的結果為3^5即0x0011 ^ 0x0101 = 0x0110
對0x0110,第1位(由低向高,從0開始)就是1。因此整個陣列根據第1位是0還是1分成兩組。
a[0] =1 0x0001 第一組
a[1] =1 0x0001 第一組
a[2] =3 0x0011 第二組
a[3] =5 0x0101 第一組
a[4] =2 0x0010 第二組
a[5] =2 0x0010 第二組
第一組有,第二組有,明顯對這二組分別執行「異或」解法就可以得到5和3了。
分析至些,相信**不難寫出,下面給出完整的源**:
[cpp]view plain
copy
//陣列中除兩個數字外,其它數字都出現了次。要求盡可能快的找出這兩個數字
//by morewindows (
#include
void
findtwonotrepeatnumberinarray(
int*a,
intn,
int*pn1,
int*pn2)
void
printfarray(
inta,
intn)
intmain()
;int
a[maxn] = ;
printf("陣列為: \n"
);
printfarray(a, maxn);
intnnotrepeatnumber1, nnotrepeatnumber2;
findtwonotrepeatnumberinarray(a, maxn, &nnotrepeatnumber1, &nnotrepeatnumber2);
printf("兩個不重複的數字分別為: %d %d\n"
, nnotrepeatnumber1, nnotrepeatnumber2);
return
0;
}
執行結果如下所示:
bufferedReader進一步理解
public static void main string args string mystring system.out.println 請輸入明文 bufferedreader buf new bufferedreader new inputstreamreader system.in try...
進一步理解委託
前面一篇文章介紹了委託的基本知識,接下來就進一步研究一下委託。其實,剛開始覺得委託型別是乙個比較難理解的概念,怎麼也不覺得下面的 assembleiphonehandler 是乙個型別。public delegate void assembleiphonehandler 按照正常的情況,如果我們要建...
前端進一步理解
非常開心能夠在這裡作工作匯報和個人總結,這是我鼓起勇氣的結果,算是成功了一半,呵呵。從剛來公司茫然失措的菜蛋到現在稍顯成熟的菜鳥,我知道我離成功又進了一步。以下是我對前端的理解和對自己這段時間的總結 一 前端職責 前端開發是由網頁製作演變而來的,它的主要職能就是把 的介面更好地呈現給使用者,主要包括...