異或是乙個數**算符,應用於邏輯運算,計算機符號為「eor」。
在二進位制中,規則為:
1^0 = 1
1^1 = 0
0^0 = 0
也就是相同為0,不同為1,也可以理解為不帶進製的二進位制加法。
舉例:5 ^ 3 = 6
5二進位制:0 1 0 1
3二進位制:0 0 1 1
異或: 0 1 1 0 = 6
1、歸零率:a ^ a = 0(自己異或自己結果為0)
2、恒等率:a ^ 0 = a(與0異或結果不變)
3、交換律:a ^ b = b ^ a
4、結合律:a ^ b ^ c = a ^ (b ^ c )
1、在不使用額外變數的前提下,完成兩個數的交換。
public
class
eor_01
private
static
void
eorswap
(int a,
int b)
private
static
void
tempswap
(int a,
int b)
}
2、在一堆非空的整數陣列中,只有一種數字出現了奇數次,其他數都出現了偶數次,找出這個奇數次的數字。
public
class
eor_02
;//一般的方式,利用hash統計每個數出現的次數,然後找出奇數的數字。
system.out.
println
(findoddnumberbyhash
(nums));
//eor方式
system.out.
println
(findoddnumberbyeor
(nums));
}private
static
intfindoddnumberbyeor
(int
nums)
return oddnumber;
}private
static
intfindoddnumberbyhash
(int
nums)
for(map.entry
entry : map.
entryset()
)}return0;
}}
3、在乙個長度為11陣列中,放入1-10個數字,每個數字均出現了一次,再額外隨機放入乙個1-10的重複數字,找出這個重複的數字。
例如:[1,2,3,4,5,6,7,8,9,10,1],重複數字為1,[1,2,3,4,5,6,7,8,9,10,4],重複數字為4。
思路與上一題類似,變相的找出奇數次的數字。
public
class
eor_03
int onetimes = random.
nextint
(nums.length -1)
+1; system.out.
println
("重複出現的數:"
+ onetimes)
; nums[nums.length -1]
= onetimes;
system.out.
println
("打亂前:"
+ arrays.
tostring
(nums));
//打亂陣列順序,只是為了陣列中數字隨機的演示效果,與演算法本身無關。
shuffle
(nums)
; system.out.
println
("打亂後:"
+ arrays.
tostring
(nums));
findonetimesnumber
(nums)
;findonetimesnumberbyeor
(nums);}
private
static
void
findonetimesnumberbyeor
(int
nums)
//再把結果與 1-10 分別異或一次,最終得到的數就是重複出現的
for(
int i =
1; i < nums.length; i++
)
system.out.
println
("eor方式找出重複出現的數:"
+ k);}
private
static
void
findonetimesnumber
(int
nums)
for(
int i =
0; i < nums.length; i++
) system.out.
println
("累加方式找出重複出現的數:"
+(s2 - s1));
}private
static
void
shuffle
(int
nums)
}}
4、乙個陣列中,有兩種數出現了奇數次,其他都出現了偶數次,找出這兩種數。
public
class
eor_04
;findtwooddnumberbyeor
(nums);}
private
static
void
findtwooddnumberbyeor
(int
nums)
/** * 從k中隨便找乙個二進位制位上,下標為1的,k & (~k + 1)可以找到二進位製上最右側的1(只要找到下標有1的位置就可以了,哪乙個無所謂,這裡用個演算法取巧,得到最右側的1)。
* 假設這個1在第2位,那麼陣列中就分為兩類數,一類是第2位為1的,一類是第2位為0的。
* 就等於把兩個奇數拆分出來了。
** 驗證,假設陣列為:
** 分別計算二進位制
* 1:0001
* 8:1000
* 4:0100
* 2:0010
* 3:0011
** 兩個奇數異或結果
* 2 ^ 4 = 0110
** 0110最右側的1在第2位,即得到:0010
** 第2位為1的數有 2,3
* 第2位為0的數有 1,8,4
** 再讓陣列中所有的1,8,4異或,就得到了4
* 再用4異或 2 ^ 4 就得到了 2**/
int a = k &
(~k +1)
;int m =0;
for(
int i =
0; i < nums.length; i++)}
int n = k ^ m;
system.out.
println
("兩個奇數分別為:"
+ m +
","+ n);}
}
面試題 三進製異或
面試題 陣列a中,除了某乙個數字x之外,其他數字都出現了三次,而x出現了一次。請給出最快的方法,找到x。分析 假設該題目修改為 除了某乙個數字x之外,其他數字都出現了兩次,而x出現了一次。則可以把所有數字直接求異或,最終的結果就是x。這個很好理解。而該題目是其他數字都出現了三次,可以想到三進製異或運...
面試題 異或去重
異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。異或的性質 滿足交換律和結合律 1 交換律 a b b a 2 結合律 a b c a b ...
基礎演算法 與 或 異或運算
參加運算的兩個資料,按二進位制位進行 與 運算。運算規則 0 0 0 0 1 0 1 0 0 1 1 1 即 兩位同時為 1 結果才為 1 否則為0 例如 3 5 即 0000 0011 0000 0101 0000 0001 因此,3 5的值得1。例如 9 5 即 0000 1001 9的二進位制...