自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

異或運(yùn)算常見的應(yīng)用

開發(fā) 前端
大家可能比較熟悉 "與" 運(yùn)算 和 "或" 運(yùn)算 ,相對(duì)而言, "異或" 運(yùn)算 平常使用較少,存在感也不強(qiáng),如果不是刻意提起,可能還想不到它。

[[434244]]

大家可能比較熟悉 "與" 運(yùn)算 和 "或" 運(yùn)算 ,相對(duì)而言, "異或" 運(yùn)算 平常使用較少,存在感也不強(qiáng),如果不是刻意提起,可能還想不到它

其實(shí),"異或" 運(yùn)算也非常重要,它在加密、備份、算法等方面都有應(yīng)用,每一位開發(fā)的同學(xué)都應(yīng)該花點(diǎn)兒時(shí)間掌握它的特點(diǎn)和規(guī)律,以便在日常工作中能靈活的運(yùn)用

接下來將介紹異或運(yùn)算的一些基礎(chǔ)知識(shí)以及在實(shí)際中的一些應(yīng)用

基礎(chǔ)知識(shí)

異或是計(jì)算機(jī)中一種二元邏輯運(yùn)算, 運(yùn)算符號(hào)是 ^,它按照二進(jìn)制位進(jìn)行異或運(yùn)算,結(jié)果為 真 或 假, 它的運(yùn)算法則如下

x y x^y
0 0 0
0 1 1
1 0 1
1 1 0

表格 第一列 和 第二列 是異或運(yùn)算的兩個(gè)操作數(shù),第三列是異或運(yùn)算的結(jié)果,1 表示真,0 表示假

由表格可知:如果參與運(yùn)算的兩個(gè)二進(jìn)制位相同,則結(jié)果為 0 ,否則為 1

也就是說,異或主要用來判斷兩個(gè)值是否相同

重要的性質(zhì)

下面列出異或運(yùn)算一些重要的性質(zhì),1 表示真,0 表示假, 具體的驗(yàn)證過程比較簡(jiǎn)單,這里就省略了

1、一個(gè)數(shù)與自身異或,總是為 0

  1. x ^ x = 0 

2、 一個(gè)數(shù)與 0 異或,總是其自身

  1. x ^ 0 = x 

3、 交換性

  1. x ^ y = y ^ x 

4、 結(jié)合性

  1. x ^ ( y ^ z ) = ( x ^ y ) ^ z 

常見應(yīng)用

異或運(yùn)算本身比較簡(jiǎn)單,重點(diǎn)還是在應(yīng)用層面,上面列出的性質(zhì),在很多方面都有應(yīng)用

  • 判斷兩個(gè)數(shù)是否相等

一個(gè)數(shù)與自身異或,總是為 0,我們可以使用這一點(diǎn)來判斷兩個(gè)變量是否相等

  1. ( a ^ b ) == 0 

當(dāng) a 和 b 相等時(shí),表達(dá)式為真,否則為假

  • 不使用臨時(shí)變量交換兩個(gè)數(shù)的值

要交換兩個(gè)數(shù)的值,通常做法是借助一個(gè)臨時(shí)變量,然后再進(jìn)行交換,比如:tmp 是臨時(shí)變量,現(xiàn)需要交換 a 和 b 兩個(gè)變量值,過程如下

  1. tmp = a 
  2. a = b 
  3. b = tmp; 

利用異或的一些性質(zhì),不用臨時(shí)變量也能實(shí)現(xiàn)交換兩個(gè)數(shù)的值,具體過程如下

  1. a = a ^ b 
  2.  
  3. b = a ^ b 
  4.  
  5. a = a ^ b 

假如初始時(shí),a = 1、b = 2

第一個(gè)等式 a = a ^ b 結(jié)果是 a = 1 ^ 2 = 3

緊接著第二個(gè)等式 b = a ^ b 結(jié)果是 b = 1 ^ 2 ^ 2 = 1 ^ 0 = 1

最后一個(gè)等式 a = a ^ b 結(jié)果是 b = 1 ^ 2 ^ 1 = 1 ^ 1 ^ 2 = 0 ^ 2 = 2

可以看到,最終 a = 2、 b = 1 ,它們的值實(shí)現(xiàn)了交換

上面的三條語句還可以進(jìn)一步優(yōu)化成一條,結(jié)果如下

  1. a ^= b ^= a ^= b 
  • 簡(jiǎn)化表達(dá)式

根據(jù)交換性,可以優(yōu)化表達(dá)式中重復(fù)變量的異或運(yùn)算,比如:表達(dá)式 a ^ b ^ c ^ a ^ b 可以做如下簡(jiǎn)化

  1. a  ^  b  ^  c  ^  a  ^  b                   # 根據(jù) x ^ y  = y ^ x 
  2.  
  3. =  ( a  ^  a )  ^  ( b  ^  b )  ^  c        # 根據(jù) x  ^ x = 0 
  4.  
  5. =  0  ^  0  ^  c                            # 根據(jù) x ^ 0 = x 
  6.  
  7. = c 
  • 加密

利用異或運(yùn)算加密是很常見的加密手段,它涉及到三個(gè)變量:明文、密鑰、密文,假如它們分別記為 plain_text、 encrypt_key、 cipher_text

明文和密鑰進(jìn)行異或運(yùn)算,可以得到密文

  1. plain_text ^ encrypt_key = cipher_text 

密文和密鑰進(jìn)行異或運(yùn)算,可以得到明文

  1. cipher_text ^ encrypt_key  
  2. = ( plain_text  ^  encrypt_key ) ^ encrypt_key 
  3. = plain_text  ^ ( encrypt_key ^ encrypt_key )   # 根據(jù) x ^ ( y ^ z ) = ( x ^ z ) ^ y 
  4. = plain_text  ^  0                              # 根據(jù) x ^ x = 0 
  5. = plain_text 
  • 備份

根據(jù)異或的性質(zhì),異或運(yùn)算還可以用于文件的備份

現(xiàn)有兩個(gè)文件 filea 和 fileb,它們進(jìn)行異或運(yùn)算,會(huì)產(chǎn)生一個(gè)新的備份文件 bakfile

  1. bakfile = filea ^ fileb 

根據(jù)異或的性質(zhì),可以通過 bakfile 和 filea 得到 fileb,或者通過 bakfile 和 fileb 得到 filea

后面無論是 filea 或 fileb 文件損壞了,只要不是兩個(gè)文件同時(shí)損壞,都可以通過兩者中未損壞的文件 和 bakfile 文件,還原得到另一個(gè)文件

當(dāng) filea 文件損壞了,可以通過 fileb 和 bakfile 進(jìn)行異或運(yùn)算得到完好的 filea 文件

  1. fileb  ^  bakfile 
  2. =  fileb  ^ ( filea  ^  fileb ) 
  3. =  fileb  ^  filea  ^  fileb        # 根據(jù) x ^ ( y ^ z ) = ( x ^ z ) ^ y 
  4. =  fileb  ^  fileb  ^  filea        # 根據(jù) x ^ x = 0 
  5. =  0  ^ filea                       # 根據(jù) x ^ 0 = x 
  6. =  filea 

同樣,當(dāng) fileb 文件損壞了,可以通過 filea 和 bakfile 進(jìn)行異或運(yùn)算得到完好的 fileb 文件

f

  1. filea  ^  bakfile 
  2. =  filea  ^ ( filea  ^  fileb ) 
  3. =  filea  ^  filea  ^  fileb        # 根據(jù) x ^ ( y ^ z ) = ( x ^ z ) ^ y  
  4. =  filea  ^  filea  ^  fileb        # 根據(jù) x ^ x = 0 
  5. =  0  ^ fileb                       # 根據(jù) x ^ 0 = x 
  6. =  fileb 

解算法題

有些算法可以利用異或的思路進(jìn)行求解,下面列出力扣上的一道算法題來說明,題目如下:

  1. 一個(gè)長(zhǎng)度為 n-1 的遞增排序數(shù)組中的所有數(shù)字都是唯一的,并且每個(gè)數(shù)字都在范圍 0 ~ n-1 之內(nèi), 
  2.  
  3. 在范圍 0 ~ n-1 內(nèi)的 n 個(gè)數(shù)字中有且只有一個(gè)數(shù)字不在該數(shù)組中,請(qǐng)找出這個(gè)數(shù)字 
  4.  
  5.  
  6. 示例 1: 
  7.  
  8. 輸入: [ 0,1,3 ] 
  9.  
  10. 輸出: 2 
  11.  
  12.  
  13. 示例 2: 
  14.  
  15. 輸入: [ 0,1,2,3,4,5,6,7,9 ] 
  16.  
  17. 輸出: 8 

最快捷的解決方法是把數(shù)組的所有元素以及 0 到 n-1 之間的整數(shù) 全部進(jìn)行異或運(yùn)算

  1. arry[0] ^ arry[1] ^ arry[2] ... ^ arry[n-2] ^ 0 ^ 1 ^ 2 .... ^ (n-1) 

由于數(shù)組元素值范圍在 0 到 n-1,且所有元素值都沒有重復(fù)

所以,上述的計(jì)算式子中,0 到 n-1 每個(gè)數(shù)會(huì)出現(xiàn)兩次,只有缺少的那個(gè)數(shù)僅出現(xiàn)一次,根據(jù)異或的性質(zhì) x ^ x = 0 可知,相同值之間的異或運(yùn)算等于 0,因此算式的結(jié)果其實(shí)就是缺少的那個(gè)數(shù)

下面給出測(cè)試文件 test.cpp,代碼是用 C++ 實(shí)現(xiàn)的,可以自行用其他語言實(shí)現(xiàn)

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4.  
  5. int32_t find_missing(int32_t *ary, int32_t len) 
  6.     //數(shù)組長(zhǎng)度小于等于1,直接返回 -1 
  7.     if(len <= 1) 
  8.     { 
  9.         return -1; 
  10.     } 
  11.     //結(jié)果 
  12.     int32_t result = 0; 
  13.     //result 和 數(shù)組中每一個(gè)元素值進(jìn)行異或運(yùn)算 
  14.     for (int32_t i = 0; i < len; i++) 
  15.     { 
  16.         result ^= ary[i]; 
  17.     } 
  18.     //result 和 0 到 n 中每一個(gè)值進(jìn)行異或運(yùn)算 
  19.     for (int32_t j = 0; j <= len; j++) 
  20.     { 
  21.         result ^= j; 
  22.     } 
  23.     return result; 
  24. //編譯: g++ -g -o test  test.cpp 
  25. int32_t main(int32_t argc , char *argv[]) 
  26.     int32_t ary[] = { 0, 1, 3 }; 
  27.     int32_t result = find_missing(ary, sizeof(ary) / sizeof(int32_t)); 
  28.     std::cout << "result = " << result << std::endl; 
  29.      
  30.     return 0; 

使用 g++ -g -o test test.cpp 命令編譯,接著運(yùn)行程序,結(jié)果如下:

  1. [root@localhost test]# ./test  
  2. result = 2 

當(dāng)然,這道題目還有其他的解法,比如:利用加法來解,大家自己去思考下,這里不做介紹了

題目鏈接 https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/

小結(jié)

通過上文,我們可以看到,異或運(yùn)算在很多方面都有應(yīng)用,其實(shí),它的應(yīng)用遠(yuǎn)不止文中介紹的方面,所以,我們花時(shí)間去掌握它是非常值得做的一件事

 

責(zé)任編輯:武曉燕 來源: Linux開發(fā)那些事兒
相關(guān)推薦

2022-05-18 16:06:15

位運(yùn)算異或運(yùn)算

2022-05-23 15:02:19

異或運(yùn)算面試真題

2017-08-29 09:40:26

JavaScript代碼神經(jīng)網(wǎng)絡(luò)

2012-10-26 11:37:12

2021-08-06 10:26:14

蜂窩物聯(lián)網(wǎng)物聯(lián)網(wǎng)IOT

2012-02-02 15:24:57

2022-10-26 14:55:53

AIoT物聯(lián)網(wǎng)人工智能

2010-11-23 15:42:14

2023-02-03 16:16:34

物聯(lián)網(wǎng)

2012-02-22 20:46:24

金萬維異速聯(lián)

2010-01-04 15:12:27

Silverlight

2018-07-29 15:27:04

AI訓(xùn)練光速運(yùn)算人工智能

2012-07-25 15:56:07

2021-02-21 06:36:57

運(yùn)算技巧按位

2010-03-05 16:38:48

Python應(yīng)用范圍

2017-12-19 10:03:44

JavaLinux代碼

2019-05-29 18:35:04

Windows 10Office 365應(yīng)用程序

2011-07-21 09:12:55

2023-02-15 11:58:29

2018-05-28 08:28:24

云計(jì)算應(yīng)用場(chǎng)景
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)