聊聊位運算那些事(2)

2021-09-24 00:00:21 字數 1131 閱讀 8904

引發學習位運算的原因是在網上瀏覽到了幾道題:

有乙個給定的陣列,其中僅有乙個元素出現了一次,而其他的元素出現了兩次。問如何找出這個僅出現一次的元素呢?

解:其實看到這一題的第一反應是利用陣列下標法。但是它的空間複雜度是o(n),是時間複雜度是o(n).

但是我們可不可再優化以下,盡量降低它的複雜度?

緊接著,又想到了利用雜湊表儲存每個元素出現的次數,當乙個元素出現兩次時,就從表中刪除,最後只有乙個元素。此舉可以降低空間複雜度,但是並不是最優的選擇。

而推薦的解法就是利用異或運算。

舉例說明:

1,2,1,2,5

運用異或後,1^2^1^2^=1^1^2^2^5。so根據異或的性質,最後0^5為5。

int find(int arr[100])

return temp;//直接返回了答案!

}

判斷乙個數是不是2的冪次

解:我們觀察是二的冪次數的二進位制形式可以發現,其只有一位為1,其餘位均為0.

那麼我們可以根據這個性質來進行分析。

我們可以用到x&(x-1)這一操作。當最後的結果是0時,說明只有一位是1,說明其是二的冪次。

我們下邊進行舉例說明:如該數是1000,則其減1後的結果為0111,進行與運算後的結果為0;如果這個數是10100,減一後的結果是10011,進行與運算後的結果是1。

找出不大於n的最大的2的冪指數;

解:按二進位制的形式來看,如10100,結果應該是最左邊的非0位,故為4。所以我們得找出一種操作,是得10100000變為11111111,然後加1,得到了100000000,然後100000000>>1=10000000。

接下來,重點是變為全1的操作。假設這個數是8位的,而我們一定可以知道第k位一定是1((從左至右數的第乙個非0位)。我們接下來讓其右移一位,並進行或運算,得到的結果為第k位,第k+1位,一定是1。緊接著我們再進行右移兩位第,則或運算後,第k,k+1,k+2,k+3位均為一定為1。依次類推進行右移四位,則可以保證這八位一定全為1.

x|x>>1;

x|x>>2;

x|x>>4;

之後再進行減一後移位操作。

int find(int x)

聊聊字元編碼那些事

計算機字元編碼的歷史 在windows作業系統下可以通過命令列模式檢視系統使用的字符集,如下圖所示 從圖中看到,活動頁 為936,代表gb2312 簡體中文 作者的個人計算機安裝的是windows10簡體中文版。microsoft visual studio整合開發環境採用的字元編碼是作業系統使用的...

聊聊fork的那些事

參加了一場面試 學會了乙個知識點 fork之後發生了 什麼 我很正常的做出了回答,對父程序的記憶體進行了複製。fork之後 在早期的unix的系統是通過複製的 為系統分配 記憶體頁 初始化記憶體頁 將父程序的記憶體內容分配到子程序當中 這造成了什麼?這造成了cpu和記憶體的浪費,如果乙個父程序1個g...

聊聊UTC時間那些事

最近做了乙個微控制器的專案,採用外接rtc模組,而外接模組只有年月日時分秒暫存器,需要用到時間戳對發生的事件和日誌做記錄。於是就想做乙個使用在微控制器上的utc轉unix時間戳的庫。先說一下什麼是utc時間,utc是coordinated universal time縮寫,中文又稱協調世界時。在了解...