【劍指offer15.二進制中1的個數】——位操作(左移右移等)

目錄

二進制的表示

二進制的位操作

應用: 劍指offer15.統計二進制中1的個數(多種方法,位右移操作、與操作等)


轉自:https://www.jianshu.com/p/3a31065a8e58

紅色為自己添加

我們都知道在計算機中所有的信息最終都是以二進制的0和1來表示,而有些算法是通過操作bit位來進行運算的,這就需要我們了解Python中如何去表示二進制,又如何是進行位運算的。

二進制的表示

0b111 類型是整型,一般為二進制32整型或者16整型,常見的是二進制8位整型

bin(n)可以將一個十進制或者其他進制的整型轉化成二進制,返回的類型是字符串表示的二進制整型

n = 0b101
print(type(n))
print(type(bin(n)))

<class 'int'>
<class 'str'>

首先在Python中可以通過以"0b"或者"-0b"開頭的字符串來表示二進制,如下所示

print 0b101 # 輸出5
print 0b10  # 輸出2
print 0b111 # 輸出7
print -0b101 # 輸出-5

由此可知我們用二進制表示的數字在打印之后會變成我們更為熟悉的十進制數,更容易被人理解。
當我們需要看十進制數字的二進制表示時,可以使用bin函數

bin(5)  # 輸出0b101

二進制的位操作

首先一點需要明確的是所有的運算(包括位操作)在計算機內部都是通過補碼形式來進行運算的,關于補碼可以參考文章原碼,反碼和補碼,計算機內部運算示意圖如下:


此部分轉自:https://blog.csdn.net/weixin_39671935/article/details/113980497

先簡單說一些概念:

原碼:從符號位開始表示,1是正數,0是負數

反碼:正數的原碼反碼補碼都是一樣的。

負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反

比如-5轉成二進制原碼1101,在算出反碼1010

補碼:正數的原碼反碼補碼都是一樣的。

負數的補碼是反碼+1


?

?

?

在Python中提供了如下二進制的位操作:

>>  #右移
<<  #左移
|   #位或 
&   #位與
^   #位異或
~   #非

下面我們分別來看下:

左移

0b11 << 2   #輸出為12, 即0b1100
5 << 2      #輸出為20, 即0b10100
-2 << 2     #輸出為-8
5 << 64     #輸出為92233720368547758080L
  1. 以0b11為例,0b11的補碼就是0b11,所以左移就是將所有的0和1的位置進行左移,移位之后將空位補0。
  2. 負數的左移相對來說就比較復雜,以-2 << 2為例,-2的原碼是10000000000000000000000000000010(32位系統),其補碼為11111111111111111111111111111110,左移之后變為11111111111111111111111111111000,再轉化為原碼即10000000000000000000000000001000,也就是-8,也就是-2*(2**2)=-8
  3. 左移超過32位或者64位(根據系統的不同)自動轉化為long類型。
  4. 左移操作相當于乘以2**n,以5 << 3為例,相當于5(2*3),結果為40。

右移

0b11 >> 1   #輸出為1, 即0b1
5 >> 1      #輸出為2,即0b10
-8 >> 3     #輸出為-1     
  1. 在Python中如果符號位為0,則右移后高位補0,如果符號位為1,則高位補1;
  2. 同樣需要先轉化為補碼再進行計算,以-8 >> 3為例,-8的原碼為10...01000,相應的補碼為11...11000,右移后變為1...1,相應的原碼為10...01,即-1。
  3. 右移操作相當于除以2**n,8 >> 3相當于8/(2**3)=1

0b110 | 0b101   #輸出7,即0b111
-0b001 | 0b101  #輸出-1

同樣是轉化為補碼后再進行或運算, 只要有一位有1就為1。
所以或運算常常用于mask技術中的打開開關,即針對某一位把其置為1
比如將某個數字的第三位置為1,我們可以將mask設置為0b100,然后再或運算

mask = 0b100
0b110000 | mask  #turn on bit 3

0b110 & 0b011   #輸出2,即0b010

?與運算常常用于mask技術的關閉開關,即針對某一位把其置為0

mask = 0b10
0b111111 & mask  #turn off bit 2

異或

0b111 ^ 0b111   #輸出0
0b100 ^ 0b111   #輸出3

異或常用于將所有的位反轉

0b1010 ^ 0b1111  #輸出5,即0b0101

?非

~0b101  #輸出2,即0b010
~-3     #輸出2

?非運算就是把0變1,1變0,唯一需要注意的是取非時符號位也會變換,比如-3,原碼是10...011,補碼是11...101,取非后變為00...010,由于符號位為0,所以對應的原碼即為其本身,即2。

?

二進制的減法:

設n=0b1010

則n-1=0b1001

減法原則和十進制的減法一致,只是向前借一的時候,一表示的不是10而是2,加法也是一樣,滿2進1

0b1010
-????1
?????=
0b1001

?

應用: 劍指offer15.統計二進制中1的個數(多種方法,位右移操作、與操作等)

請實現一個函數,輸入一個整數(以二進制串形式),輸出該數二進制表示中 1 的個數。例如,把 9 表示成二進制是 1001,有 2 位是 1。因此,如果輸入 9,則該函數輸出 2。

?

示例 1:

輸入:00000000000000000000000000001011
輸出:3
解釋:輸入的二進制串 00000000000000000000000000001011 中,共有三位為 '1'。

示例 2:

輸入:00000000000000000000000010000000
輸出:1
解釋:輸入的二進制串 00000000000000000000000010000000 中,共有一位為 '1'。

代碼實現:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/5/17 17:59
# @Author  : @linlianqin
# @Site    : 
# @File    : 劍指 Offer 15. 二進制中1的個數.py
# @Software: PyCharm
# @description:
'''
請實現一個函數,輸入一個整數(以二進制串形式),輸出該數二進制表示中 1 的個數。
例如,把 9 表示成二進制是 1001,有 2 位是 1。因此,如果輸入 9,則該函數輸出 2。
''''''
思路:將n變成二進制形式,然后計數'1'的個數
'''
class Solution:def hammingWeight(self, n: int) -> int:return bin(n).count('1')# 將其轉化為列表后再諸位變成整數進行相加def hammingWeight1(self,n):return sum(map(int,bin(n)[2:]))n = 0b101
print(Solution().hammingWeight(n))
print(Solution().hammingWeight1(n))# 優化思路,充分利用二進制的位操作
def hammingWeight2(n):# 這里諸位將二進制的數字和1進行運算,若結果為1,則說明當前位置值為1,否則為0count = 0while n: # 當n不全為0時count += n&1 # 這里是進行位與操作,這里的與操作默認是從高位開始的,因此需要進行右移n >>= 1return count
print(hammingWeight2(n))#優化,上述方法進行的是諸位運算,還可以繼續優化,巧妙的利用n&n-1,二進制的減法和十進制一樣,因此能夠檢測出最低位的1,即n-1
# n-1會使得最低位的1及后面的0發生變換,1-0,0-1,然后利用n&n-1來更新n,這樣來達到計數效果
def hammingWeight3(n):count = 0while n:count += 1n &= n-1return count
print(hammingWeight3(n))
print(type(n))
print(type(bin(n)))

2
2
2
2
<class 'int'>
<class 'str'>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255941.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255941.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255941.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java 異常處理機制(java 編程思想)

一、概念  “異常”這個詞有“我對此感到意外”的意思。問題出現了&#xff0c;你也許并不清楚該如何處理&#xff0c;但你的確知道不應該置之不理&#xff1b;你要停下來&#xff0c;看看是不是有別人或在別的地方&#xff0c;能夠處理這個問題。只是在當前的環境中還沒有足夠…

怎樣在CentOS 7.0上安裝和配置VNC服務器

這是一個關于怎樣在你的 CentOS 7 上安裝配置 VNC 服務的教程。當然這個教程也適合 RHEL 7 。在這個教程里&#xff0c;我們將學習什么是 VNC 以及怎樣在 CentOS 7 上安裝配置 VNC 服務器 。 我們都知道 這是一個關于怎樣在你的 CentOS 7 上安裝配置 VNC 服務的教程。當然這個教…

MOTOMAN機器人網絡控制的實現

最初程序員在Unix系統下使用Berkeley Socket編寫網絡程序&#xff0c;隨著Windows操作系統的普及&#xff0c;Microsoft、Sun等公司聯合開發了Winsock接口API。它實質上是一種進 程間通信&#xff0c;將之從單機環境擴展到網絡環境以適合于開發主機/客戶機通信程序。網絡通信的…

【劍指offer】——【python中return函數中的and和or表達式的返回值】

目錄 1、# and 結果為真&#xff0c;返回最后一個表達式的結果&#xff0c;若結果為假返回第一個為假的表達式的結果 2、# or 結果為真&#xff0c;返回第一個為真的表達式的結果&#xff0c;若結果為假&#xff0c;返回最后一個表達式的結果 3、應用[劍指 Offer 64. 求12…n…

Spring Cloud構建微服務架構:消息驅動的微服務(入門)【Dalston版】

2019獨角獸企業重金招聘Python工程師標準>>> 之前在寫Spring Boot基礎教程的時候寫過一篇《Spring Boot中使用RabbitMQ》。在該文中&#xff0c;我們通過簡單的配置和注解就能實現向RabbitMQ中生產和消費消息。實際上我們使用的對RabbitMQ的starter就是通過Spring C…

CXF 客服端調用報錯

服務端已經發布了WSDL&#xff0c;現在在客服端生成web service客服端代碼&#xff0c;在eclipse中新建一個project&#xff0c;然后new->web services->web service client生產客戶端代碼 在調用的時候報如下錯誤 解決&#xff1a;缺少axis相應的jar包&#xff0c;加入包…

20145225 《信息安全系統設計基礎》第10周學習總結

cp1.c 進行復制文件的操作&#xff0c;需要有源文件和目的文件&#xff0c;第一次命令沒有加入所以沒有正常完成復制文件的操作fileinfo.c 用來實現顯示文件信息。先判斷命令是否有操作數&#xff0c;有的話才能繼續進行下去&#xff0c;如果沒有報錯就打印出來相關文件信息&am…

做演員是圓夢 做生意學會面對現實

田樸珺是一位擁有多重身份的女性。她是一名演員&#xff0c;也是一位商人&#xff0c;還擔任過電影《中國合伙人》的制片人。 作為演員&#xff0c;田樸珺的作品并不是很多&#xff0c;也一直不溫不 火。但這并不代表她將放棄演藝生涯。她表示&#xff0c;如果機會合適&…

【深度學習】——模型評估指標MAP計算實例計算

目錄 一、知識儲備 1、IOU——交集面積與并集面積之比 2、混淆矩陣&#xff08;TP、FP、FN、TN&#xff09; 問題1&#xff1a;上面的TP等具體是如何計算得到的&#xff1f; 3、精度precision&召回率recall 二、ap計算實戰 1、計算流程 1&#xff09;準備數據&#xf…

第 52 章 Web Server Optimization

系統配置 Intel(R) Xeon(TM) CPU 3.00GHzMemory 4GEthernet adapter 1000M52.1. ulimit 查看 ulimit ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited pending signals …

hdu5489 Removed Interval dp+線段樹優化

現在看這題居然直接秒了。。。去年看的時候還以為神題。。 設以第i項為結尾的lis前綴為f[i]&#xff0c;以第j項為結尾的lis后綴為g[i]&#xff0c;如果求出f[i]和g[j]&#xff0c;然后枚舉i&#xff0c;快速找到最大的滿足a[j]>a[i]的g[j]就可以了。注意到如果將f[i]從后往…

JS原型鏈理解

1. 每個對象都有原型屬性(__proto__)2. 對象的原型(__proto__)指向其構造函數(Constructor)的prototype屬性3. 構造函數(Constructor)的prototype屬性本身也是一個對象&#xff0c;其原型(__proto__)亦指向其構造函數的prototype4. 如此形成一個鏈式結構&#xff0c;而Construc…

【深度學習】——2021年FPN特征金字塔

#!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2021/4/22 17:06 # Author : linlianqin # Site : # File : fpn.py # Software: PyCharm # description:其搭建的基本流程和resnet是一致的&#xff0c;只是將每一層的卷積結果保存了起來import torch impo…

NoSQL分類及ehcache memcache redis 三大緩存的對比

NoSQL分類 由于NoSQL中沒有像傳統數據庫那樣定義數據的組織方式為關系型的&#xff0c;所以只要內部的數據組織采用了非關系型的方式&#xff0c;就可以稱之為NoSQL數據庫。目前&#xff0c;可以將眾多的NoSQL數據庫按照內部的數據組織形式進行如下分類&#xff1a; Key/Value的…

52.4. APC Cache (php-apc - APC (Alternative PHP Cache) module for PHP 5)

$ apt-cache search php-apc php-apc - APC (Alternative PHP Cache) module for PHP 5$ sudo apt-get install php-apcapc cache 狀態監控 http://pecl.php.net/package/APC 下載解包找到apc.php,放到web服務器上 原文出處&#xff1a;Netkiller 系列 手札 本文作者&#xff1…

樂視云計算基于OpenStack的IaaS實踐

本文作者岳龍廣&#xff0c;現在就職于樂視云計算有限公司&#xff0c;負責IaaS部門的工作。 從開始工作就混在開源世界里&#xff0c;在虛擬化方面做過CloudStack/Ovirt開發&#xff0c;現在是做以OpenStack為基礎的樂視云平臺。所以對虛擬化情有獨鐘&#xff0c;也對虛擬化/云…

【深度學習】——如何提高map值

目錄 代碼獲取 map原理 map提高技巧 技巧總結&#xff1a; 實戰&#xff1a; 1、效果不佳map55.55% 1&#xff09;單獨調整get_dr_txt.py中的self.iou 0.3 2&#xff09;單獨調整get_map,py中的minoverlap: 3)同時調整minoverlap和self.iou 本文是在faster_rcnn模型的…

每日站立會議個人博客(沖刺周)-Wednesday

時間未完成不知道如何獲取具體標簽里的內容正在做爬蟲技術之獲取標簽里的內容將要做對運用爬蟲技術獲取的數據進行處理轉載于:https://www.cnblogs.com/andibier/p/8075098.html

數據庫水平切分的實現原理解析——分庫,分表,主從,集群,負載均衡器(轉)...

第1章 引言 隨著互聯網應用的廣泛普及&#xff0c;海量數據的存儲和訪問成為了系統設計的瓶頸問題。對于一個大型的互聯網應用&#xff0c;每天幾十億的PV無疑對數據庫造成了相當高的負載。對于系統的穩定性和擴展性造成了極大的問題。通過數據切分來提高網站性能&#xff0c;橫…

【深度學習】——糾錯error: Unable to find vcvarsall.bat:關于安裝pycocotools

1、安裝包下載 大佬改寫支持 Windows 的 COCO 地址&#xff1a;https://github.com/philferriere/cocoapi 下載后如下&#xff1a; 進入pythonAPI 先后運行&#xff1a; python setup.py build_ext --inplacepython setup.py build_ext install 出現以下標志時&#xff0c…