在Python中,如何用一行代碼去判定整數二進制中的連續 1
文章筆記來自於猿人學公眾號,公眾號搜索:猿人學python
微信掃碼即可關註
利用字節位操作如何判斷一個整數的二進制是否含有至少兩個連續的1 的方法有多種,大家第一反應應該想到的是以下的第一種方法。
方法一:從頭到尾遍歷一遍每一位即可找出是否有連續的1存在
這個方法是最普遍的、第一感覺就能想到的方法,下面我們看一下它的具體實現:
Python代碼:
def method_1(n) : last_is_one= False this_is_one = False while n > 0: this_is_one = n % 2 if this_is_one and last_is_one: return True n = n >> 1 last_is_one = this_is_one return False
上面的實現中,對於整數n先做取余運算(n % 2),如果余數為1,則n的最後一位是1,否則為0,並用this_is_one記錄當前位;
然後判斷一下,這次和上次的最後一位是不是都是1,如果是,則可以判定該整數有兩個連續的1,否則把n向左移一位,繼續循環開始的取余操作。
雖然通過上面第一種方法也可以實現,但是這樣的操作復雜度大家都是可以看到的,比較耗時間,效率也較低。
下面這種方法在python中運行一行代碼即可實現。
方法二:無需遍歷每一位,但還是位操作:移一位(左移、右移皆可)然後和原數“位與”一下即可
這個原理不復雜,思考一下:
如果有兩個連續的位為1,原數和移為後的數“位與”操作,就是會發生這兩個連續的1進行“位與操作”,則結果中必出現至少一個位為1 (1&1 == 1),結果不為零;
如果沒有至少兩個連續的位為1,則1的兩邊都是0,原數和移為後的數“位與”操作,就是1與兩邊的0進行“位與操作”,則所有的1都變成了0 (1&0 == 0),結果必為零;
由以上推理,算法就簡化的很多,只用一行代碼即可搞定。
Python代碼:
def foo2(n): return (n & n<<1) > 0
那麽,上面兩種方法的效率差多少呢,我們來測試一下看看:
Python代碼
def test(func, loops): b = time.time() for n in range(loops): func(n) e = time.time() print(loops, ‘, time cost:‘, e-b) if __name__ == ‘__main__‘: test(foo1, 10**6) test(foo2, 10**6)
看一下運行結果,循環1百萬次,方法二的速度是方法一的4倍多:
<function method_1 at 0x7f60de787e18> 1000000 , time cost: 0.6687741279602051
<function method_2 at 0x7f60de75b598> 1000000 , time cost: 0.16364359855651855
在Python中,如何用一行代碼去判定整數二進制中的連續 1