進一步理解異或

2021-06-13 19:00:54 字數 1778 閱讀 7160

首先來看題目要求:

在乙個陣列中除兩個數字只出現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 按照正常的情況,如果我們要建...

前端進一步理解

非常開心能夠在這裡作工作匯報和個人總結,這是我鼓起勇氣的結果,算是成功了一半,呵呵。從剛來公司茫然失措的菜蛋到現在稍顯成熟的菜鳥,我知道我離成功又進了一步。以下是我對前端的理解和對自己這段時間的總結 一 前端職責 前端開發是由網頁製作演變而來的,它的主要職能就是把 的介面更好地呈現給使用者,主要包括...