ICS Return 1 when x contains an odd number of 1s,0 otherwise(判斷二進制表示中1的個數是否爲奇數)

本題棘手的地方在於不能用循環語句,並且最多隻能包含12個算術運算、位運算和邏輯運算。


思路找了非常久,用了從一般到特殊,才慢慢發現規律。


首先來看只用兩個bit的情況,未知數x共有四種(00,01,10,11),若要判斷1的個數奇偶,不難發現只需用最高位異或最低位就可實現,即 x^(x>>1),如果結果爲1,那麼有奇數個,否則有偶數個。


從中不難看出對於32位的x,若 y1=x^(x>>1),那麼y1的第i位爲1表示x的第i位與第i+1位有奇數個1,y1的第i位爲0表示x的第i位與第i+1位有偶數個1。由於奇數、偶數都是在Abel{0,1}中算,因此直接繼續對y1操作,即只關心奇偶。


因此y2=y1^(y1>>2),即y2的第i位表示x的第i位到第i+3位的1的個數的奇偶。


不斷重複此過程,直至y5,y5的第i位表示x的第i位到第i+32位的1的個數的奇偶。y5的第0位即是答案。

int odd_number(unsigned x)函數代碼如下:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;



int odd_number(unsigned x){
    x=x^(x>>1);
    x=x^(x>>2);
    x=x^(x>>4);
    x=x^(x>>8);
    x=x^(x>>16);
    
    return x&0x1;
}


int main(){
    int k;
    while(cin>>k){
        cout<<odd_number(k)<<endl;
    }
    
}


再補充一點,另一種做法也可以,而且思路比上面的做法更加直接,讀者可以自己體會。 思路和上面是一樣的。

代碼如下:

int odd_number(unsigned x){
    x=x^(x>>16);
    x=x^(x>>8);
    x=x^(x>>4);
    x=x^(x>>2);
    x=x^(x>>1);
    
    return x&0x1;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章