題目以下:數組
Description |
||
海明距離是在指二進制狀況下,一個整數變成另一個整數須要翻轉的位數。好比2轉換到3須要翻轉1位,因此2到3的海明距離是1。給你兩個正整數x和y,(x,y<=1,000,000,000)求它們的海明距離。 輸入 第一行是一個整數N,表示樣例的個數。之後每行兩個整數x和y。 輸出 每行輸出一個整數,及對應樣例的結果。
|
||
Sample Input |
||
2 1 2 4 7 |
||
Sample Output |
||
2 2 |
分析思路:spa
簡單來講就是一個多樣例輸入,對於每一組輸入都轉化成二進制而後進行邏輯上的異或運算,即比較兩個二進制數對應的每一位,同爲0或同爲1則返回0,一個爲0一個爲1則返回1。例如2的二進制表示爲……00000010,3的二進制表示爲……00000011,他們進行異或運算的結果爲……00000001,也就是最後一位不一樣須要「翻轉」。因此海明距離實際就就是看兩個數進行二進制的異或運算後爲1的位數有幾位。.net
核心問題:code
有了上面的思路,如今的問題就是要怎麼把輸入的十進制的數轉化爲二進制進行異或運算呢?開始想的是把十進制數經過取模運算一步步轉換成二進制數儲存在數組中,而後利用循環分別比較每一位,兩個數在那一位上的數不相同則計數+1。blog
後來纔回憶起來C語言裏提供了「位運算符」,能夠直接經過a^b對這兩個十進制數的二進制形式進行異或運算(不須要本身轉換進制)。詳情可參考【http://blog.csdn.net/chen825919148/article/details/8049069】ip
運算符 | 做用 |
& | 位邏輯與:按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均爲1時,結果位才爲1 ,不然爲0。參與運算的數以補碼方式出現。 例如:9&5可寫算式以下: 00001001 (9的二進制補碼)&00000101 (5的二進制補碼) 00000001 (1的二進制補碼)可見9&5=1。 |
| | 位邏輯或:按位或運算符「|」是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個爲1時,結果位就爲1。參與運算的兩個數均以補碼出現。 例如:9|5可寫算式以下: 00001001|00000101=00001101 (十進制爲13)可見9|5=13 |
^ | 位邏輯異或 :按位異或運算符「^」是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果爲1。參與運算數仍以補碼出現,例如 9^5可寫成算式以下: 00001001^00000101=00001100 (十進制爲12) |
~ | 位邏輯反 :求反運算符~爲單目運算符,具備右結合性。 其功能是對參與運算的數的各二進位按位求反。例如~9的運算爲: ~(0000000000001001)結果爲:1111111111110110 |
>> | 右移:右移運算符「>>」是雙目運算符。其功能是把「>> 」左邊的運算數的各二進位所有右移若干位,「>>」右邊的數指定移動的位數。例如:設 a=15,a>>2 表示把000001111右移爲00000011(十進制3)。應該說明的是,對於有符號數,在右移時,符號位將隨同移動。當爲正數時, 最高位補0,而爲負數時,符號位爲1,最高位是補0或是補1 取決於編譯系統的規定。 |
<< | 左移:左移運算符「<<」是雙目運算符。其功能把「<< 」左邊的運算數的各二進位所有左移若干位,由「<<」右邊的數指定移動的位數,高位丟棄,低位補0。例如: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後爲00110000(十進制48)。 |
最後附上個人程序源碼:源碼
1 #include<stdio.h> 2 int main() 3 { 4 int n,i,a,b; 5 scanf("%d",&n); 6 for(i=1;i<=n;i++) 7 { 8 scanf("%d%d",&a,&b); 9 a^=b; //a,b的異或運算,把運算結果儲存在a中; 10 b=0; //把b重置爲0,用於計數; 11 while(a) 12 { 13 if(a&1) //二進制a於(二進制)...00001的且運算,同1爲1,其他爲0;即異或運算後的結果最後一位爲1時計數+1 14 b++; 15 a>>=1; //對a進行右移位運算,去掉最低位,下一次循環比較上一位,直至a的值爲0; 16 } 17 printf("%d\n",b); //輸出異或運算後結果爲1的位數有幾位,即兩個數的海明距離; 18 } 19 return 0; 20 }