<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go:異或運(yùn)算的妙用

          共 3428字,需瀏覽 7分鐘

           ·

          2023-08-31 23:58

          概述

          異或運(yùn)算 通過(guò)對(duì)兩個(gè)相同長(zhǎng)度的二進(jìn)制數(shù)進(jìn)行逐位比較,若對(duì)應(yīng)位的值不同,結(jié)果為 1, 否則結(jié)果為 0, Go 語(yǔ)言中使用的運(yùn)算符號(hào)為 ^

          下面舉幾個(gè)簡(jiǎn)單的小例子:

          0 ^ 0 = 0

          0 ^ 1 = 1

          1 ^ 0 = 1

          1 ^ 1 = 0

          圖片來(lái)源: https://www.build-electronic-circuits.com/xor-gate/

          運(yùn)算定律

          交換律

          x ^ y = y ^ x

          結(jié)合律

          x ^ (y ^ z) = (x ^ y) ^ z

          任何數(shù)與自身進(jìn)行異或運(yùn)算,結(jié)果都為 0

          x ^ x = 0

          任何數(shù)與 0 進(jìn)行異或運(yùn)算, 結(jié)果為其自身

          x ^ 0 = x

          有了上面的理論基礎(chǔ)之后,下面來(lái)看下異或運(yùn)算的幾個(gè)應(yīng)用。


          交換兩個(gè)變量的值

          有個(gè)經(jīng)典的筆試題:交換兩個(gè)變量的值,不能使用第三個(gè)變量。

          解法一

          利用 Go 語(yǔ)言的原生 “騷操作” :

          package main

          import "fmt"

          func main() {
           x, y := 12
           
           x, y = y, x

           fmt.Printf("x = %d, y = %d\n", x, y) 
           // 輸出: x = 2, y = 1
          }

          當(dāng)然了,如果在真實(shí)面試中這樣寫,只能回去等消息了。

          解法二

          利用加法分配率

          package main

          import "fmt"

          func main() {
           x, y := 12

           x += y    // x = 3
           y = x - y // y = 1
           x -= y    // x = 2

           fmt.Printf("x = %d, y = %d\n", x, y)
           // 輸出: x = 2, y = 1
          }

          解法三

          異或運(yùn)算性質(zhì): 三個(gè)值中的任意兩個(gè)值進(jìn)行異或運(yùn)算,都可以得出第三個(gè)值。

          package main

          import "fmt"

          func main() {
           x, y := 12

           x ^= y    // x = 3
           y = x ^ y // y = 1
           x ^= y    // x = 2

           fmt.Printf("x = %d, y = %d\n", x, y)
           // 輸出: x = 2, y = 1
          }

          加密解密

          異或運(yùn)算可以實(shí)現(xiàn)簡(jiǎn)單高效的加密解密,例如:

          • 明文數(shù)據(jù)為 text
          • 密鑰為 secret
          • 密文數(shù)據(jù)為 token
          # 服務(wù)端響應(yīng)時(shí),返回加密數(shù)據(jù)

          token = text ^ secret

          #
           服務(wù)端接收到請(qǐng)求時(shí),解密數(shù)據(jù)

          text = token ^ secret

          這個(gè)經(jīng)典應(yīng)用在 CSRF 攻擊防范 一文中已經(jīng)講過(guò),這里不再贅述,感興趣的讀者可以跳轉(zhuǎn)閱讀。

          數(shù)據(jù)備份

          將數(shù)據(jù) x 和數(shù)據(jù) y 進(jìn)行異或運(yùn)算得到備份數(shù)據(jù) z, 然后將三個(gè)數(shù)據(jù)同時(shí)保存 (備份數(shù)據(jù) z 保存到可用性更高的數(shù)據(jù)中心),之后不論數(shù)據(jù) x 或數(shù)據(jù) y 損壞了,都可以根據(jù)備份數(shù)據(jù) z 進(jìn)行恢復(fù)。

          簡(jiǎn)化計(jì)算

          在多個(gè)值進(jìn)行計(jì)算的場(chǎng)景中,可以根據(jù)運(yùn)算定律簡(jiǎn)化計(jì)算過(guò)程:

          x ^ y ^ z ^ x ^ y

          上述計(jì)算式子根據(jù)交換律,可以得到:

          x ^ y ^ z ^ x ^ y

          根據(jù) “任何數(shù)與自身進(jìn)行異或運(yùn)算,結(jié)果都為 0” 運(yùn)算定律,可以得到:

          0 ^ 0 ^ z = z

          算法設(shè)計(jì)

          異或運(yùn)算經(jīng)常被用于設(shè)計(jì)高效的數(shù)據(jù)結(jié)構(gòu)和算法,例如之前的文章提到的 布谷鳥(niǎo)過(guò)濾器。

          LeetCode 原題

          給你一個(gè) 非空 整數(shù)數(shù)組 nums ,除了某個(gè)元素只出現(xiàn)一次以外,其余每個(gè)元素均出現(xiàn)兩次。找出那個(gè)只出現(xiàn)了一次的元素。

          要求: 必須設(shè)計(jì)并實(shí)現(xiàn)線性時(shí)間復(fù)雜度的算法來(lái)解決此問(wèn)題,且該算法只使用常量額外空間。

          # 示例 1
          輸入:nums = [2,2,1]
          輸出:1

          #
           示例 2
          輸入:nums = [4,1,2,1,2]
          輸出:4

          #
           示例 3
          輸入:nums = [1]
          輸出:1

          解題代碼如下:

          // 利用異或運(yùn)算的性質(zhì):
          // 1. 任何數(shù)和 0 做異或運(yùn)算,結(jié)果仍然是原來(lái)的數(shù)
          // 2. 任何數(shù)和其自身做異或運(yùn)算,結(jié)果是 0
          // 3. 異或運(yùn)算滿足交換律和結(jié)合律,a^b^a = b^a^a = b^(a^a) = b^0 = b
          func singleNumber(nums []int) int {
           res := 0
           for _, v := range nums {
            res ^= v
           }
           return res
          }



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲?。贿€可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 2778
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  就要日逼网 | 精品久久福利视频 | 欧美激情小说网 | 人妻精品久久久久中国字幕 | 亚洲日韩AV无码 |