異或


參考:http://blog.csdn.net/u012050154/article/details/51957530

Q:給出M個正整數,其中M-1個出現了偶數次,1一個出現了奇數次,找出這個數。

     被問到這個問題的時候,我說,把這M各數存在哈希表中,就可以找到那個出現奇數次的數了。然而,這並不是一個好的解法,面試官提示異或。(以下是摘自網絡的知識)

     1.按位與(&)【有0則0】

運算規則:0&0=0;0&1=0;1&0=0;1&1=1;

用途:

(1)清零。如果想將一個單元清零,只需與一個各位都為0的數值相與即可。

(2)取出一個數的指定位。與上 一個指定位為1,其余位為0的數值即可。

例:設x=11101100,取x的低四位。令x&00001111=00001100

     2.按位或(|)【有1則1】

運算規則:0|0=0;0|1=1;1|0=1;1|1=1;

用途:

(1)常用來對某些位置1。或上 一個指定位為1,其余位為0的數值即可。

例:設x=11101100,將x的低四位置1。令x|00001111=11101111

     3.異或(^)【同0異1】

運算規則:0^0=0;0^1=1;1^0=1;1^1=0;

用途:

(1)使特定位翻轉,異或上 一個要翻轉位數為1,其余位為0的數值即可。

例:設x=11101100,將x的低四位翻轉。令x^00001111=11100011

(2)與0異或,保留原值。

(3)基於異或運算,不引用新變量,交換兩個變量的值

a=a^b;b=a^b;a=a^b(基於加減法還有:a=a+b;b=a-b;a=a-b)

所以,該編程題的解法是:

public class FindOdd { public static void main(String[] args) { int[]a={1,1,4,4,4,5,5}; for(int i=1;i<a.length;i++){ a[0]=a[0]^a[i]; } System.out.println(a[0]); } }

 Q2:找出一串數中出現了奇數次的兩個數。

思路:

這串數中的所有數字異或,結果必定是出現奇數次的那兩個數異或的值,並且不為0,記為resExclusiveOR;

找出resExclusiveOR的第一個為1的那個位,記為indexOf1,將數組中indexOf1位為1的數分為一組num1,indexOf1位為0的數分為一組num2;

分別對num1、num2中的數做異或,其結果就是要找的那兩個數。(附代碼,源自網絡)

public class FindOdd { static void findOnce(int[]data,int length){ int num1=0; int num2=0; if(length<2) return; int resExclusiveOR = data[0]; for(int i=1;i<length;i++){ resExclusiveOR^=data[i]; } int indexOf1 = findFirstBitIs1(resExclusiveOR); for(int i=0;i<length;i++){ if(isBit1(data[i],indexOf1)){ num1=num1^data[i]; }else{ num2=num2^data[i]; } } System.out.println(num1+" "+num2); } static int findFirstBitIs1(int r){ int indexBit=0; while((r&1)==0&&(indexBit<32)){ r=r>>1; indexBit++; } return indexBit; } static boolean isBit1(int num,int index){ if(((num>>index)&1)==1) return true; else return false; } public static void main(String[] args) { int[]arr={1,4,4,1,6,6,6,7,8,8,8,7}; findOnce(arr,12); } }

 17.11.9

(1)計算某個正整數中二進制表示中1的個數

方法1:

public static void main(String[] args) { int n=7; int count=0; while(n>0) { if((n&1)==1) { count++; } n=n>>1; } System.out.println(count); }

但是該解法存在一個問題:

(補充:

右移:00001010>>2=00000010;10001010>>3=11110001

左移:00001010<<2=00101000;10001010<<3=01010000)

方法 2:

 private static int countBit(int num){ int count = 0; for(; num > 0; count++) { num &= (num - 1); } return count; }

參考:

http://www.cnblogs.com/hapjin/p/5839797.html

http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html

(2)判斷某個數的第 i 位是0還是1

private static boolean getBit(int num,int b) { return ((num & (1 << b)) != 0); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM