方法1:因為沒有異或^這樣的直接運算符,計算同或可以轉為string類型進行操作,再轉為需要的類型
string a,b,res; cin >> a>>b; //0101 1001 這里需要控制一下輸入的長度要一樣,如果不同的話要自己實現短的前面補0 int length = a.length(); for (int i = 0; i <length; ++i) { if (a[i] == b[i]) res += '1'; else res += '0'; }
cout<<res; //因為是字符串所以最后需要根據需求轉換為二進制,十進制
就是這么簡單。。。愣是弄了三個小時,查遍了整個搜索引擎,基本都是按照運算法則:~(a^b)的思想出發進行實現的,導致我一直困在這個思想里面 唉。下面記錄一下踩雷經過
1.首先想到代碼
unsigned int a, b,c; a = 0B1010; b = 0B0000; c = ~(a^b);
很明顯不會成功,因為計算機存儲a,b是按4個字節存儲的,前面會有很多0。所以最后結果是一個很大的整數。所以想:怎么才能只運算我需要的這幾位,前面的0都忽略
搜遍了百度沒找到答案,終於在stackoverflow找到了相同問題(https://stackoverflow.com/questions/49254856/perform-xnor-on-2-integers)
按照里面最后一個回答,使用bitset成功實現了基於~(a^b)思想的同或運算操作
方法二:bitset可以成功 但是有限制
unsigned int a, b,c; a = 0B1010; b = 0B0000; c = ~(a^b); cout <<bitset<4>(a)<<"\n"; cout << bitset<4>(b) << "\n"; cout << bitset<4>(c) << "\n";
但很快問題又出現了,因為bitset初始化的長度必須是常量,在編譯階段就已經確定,但我要實現的是不定長度的二進制同或運算,沒法提前精准知曉長度(即使定義很長的長度,bitset會在前面自動補0,這樣就和沒有用bitset一樣了,沒有意義)
自然的,我就想能不能像new定義數組一樣,有動態定義bitset的方法,然后在stackoverflow中找到答案(https://stackoverflow.com/questions/3134718/define-bitset-size-at-initialization)
但我並沒有去使用dynamic_bitset而是從里面一句話vector<bool>得到啟發,為什么不用模擬方法而非要用算術運算呢,雖然運算符會更快,但我目前也沒有那個必要啊。
最后,既然是模擬,數組並沒有string類型的輸入簡單。所以最后采用string類型的兩個變量模擬同或操作,這么簡單的事愣是搞了這么久 kao。。。。。。。。。。。
最后是一題同或運算的筆試題:9/8 citrix筆試第三題
題目:給一個二進制的數(例如:1010)求0000最少需要翻轉幾次才能得到1010,翻轉運算有特殊定義,當左邊的1翻轉為0時,其右邊的所有字符都取反
例子:0000—》0001—》0010—》0101—》1010 需要4次 第一次翻轉最后一個數,第二次翻轉倒數第二個數,同時其后面的取反。第三次翻轉第二個數。第四次翻轉第一個數。完成
分析:應該是按照1010和0000不斷取同或直到0,結果就是同或的次數 ,沒法驗證,應該是對的。
代碼:
string xnor(string a, string str) { int len = str.length(); string res = ""; for (int i = 0; i < len; ++i) { if (a[i] == str[i]) res += '1'; else res += '0'; } return res; } int main() { string a; cin >> a; int res = 0; while (!a.empty()) //等價於不為0,因為0101這種前面的0會拿掉 { while (!a.empty()&&a[0] == '0') a.erase(a.begin()); //去掉首部多余的0 int len = a.length(); string str = ""; while (len--) str += '0'; //初始化str為00..0,0的個數由a的長度決定 a = xnor(a, str); res++; //同或一次則++ } cout << res-1; }
