高中信息技術(Python)重難點1:數制


本文章原文地址:https://www.cnblogs.com/BobHuang/p/15497977.html,原文體驗更佳
數制在近兩年高考中分別在20年7月、21年1月和21年6月選擇題第4題出現,較為重要。

一、數的進制

進制是一種記數方式,亦稱進位計數法或位值計數法。利用這種記數法,可以使用有限種數字符號來表示所有的數值。任何一種數制都包含兩個基本要素:基和權。基又叫基數,是組成該數制的數碼個數,一般來說,k進制的基數就是k,包含k個數字;權又叫權值,是指每一個數位上的1對應的數值,可以表示為基數的若干次冪。十進制數的基數為10,十進制數234中2的權值是\(10^3\),3的權值是\(10^1\),4的權值是\(10^0\),所以十進制數234還可表示為:\(2×10^2+3×10^1+4×10^0\)

除了生活中常見的10進制,計算機還有二進制、十六進制等,我們通常用一個下標來表示該數的進制(十進制數可以忽略),也可以在該數的最后以字母來表示,見下表。

進位制 二進制 八進制 十進制 十六進制
標識 B O D H

二、十進制

我們先來看6785: 3位數的每一位 輸入一個三位數的自然數,然后一次輸出這個數的每位上的數字,並用逗號分隔。
10進制的123為什么代表123呢,\(123=1*100 + 2*10 + 3*1\),即123有1個100,2個10和3個1,也就是逢10進1,10進制中每一位只會出現0~9。

  1. 求個位最簡單,直接%10即可;
  2. 求十位呢,123有12個10,但是10個10是百位(10進制中每一位只會出現0~9,不能出現10),所以任意一個數我們//10后再求次個位也就是%10就可以求出十位;
  3. 求百位也就是有幾個100,直接//100即可。

給定任意一個數,%10得到當前位,//10拋棄當前位,不斷重復下去,即可以得到其每一位。
參考代碼

n=int(input())
# 求出個位
c=n%10
# 求出十位(拋棄個位后再求個位)
b=n//10%10
# 求出百位(拋棄個位和十位后)
a=n//100
print(a,b,c,sep=',')

三、二進制

數據在計算機內部是以二進制方式進行存儲和處理的。計算機的內部有無數個負責開關的半導體元件,0代表開關的斷,1代表開關的合。生活中的二進制有邏輯上的“真”與“假”,黑白圖像中的“黑”與“白”。二進制由德國數學家萊布尼茨發明,到20世紀40年代應用在電子計算機中。二進制是計算機的核心。

二進制數的特點是

  1. 有兩個基本數碼:0,1。
  2. 采用逢二進一的進位規則。

二進制用字母B標識,例如\(\rm{1101.01B=1\times2^3+1\times2^2+0\times2^1+1\times2^0+0\times2^{-1}+1\times2^{-2}}\)\(2^3,2^2,2^1,2^0,2^{-1},2^{-2}\)是不同位置上的權值。

二進制中的0和1可以認為是有或無,可以嘗試下6831: 蘋果裝箱問題

四、十進制轉二進制

十進制和二進制之間關系

十進制 二進制 十進制 二進制
0 0 8 1000
1 1 9 1001
2 10 10 1010
3 11 11 1011
4 100 12 1100
5 101 13 1101
6 110 14 1110
7 111 15 1111

十進制數存在和二進制數以上的轉換關系,15以內的我們可以搞定了。若給定十進制數超過15求出其2進制值表示怎么做呢?
因為二進制僅存0和1,所以若可以求出位數,可以直接分別求出每一位是0還是1。十進制正整數n的二進制位數為\(\lfloor \log_2n \rfloor + 1\)\(\lfloor {\quad} \rfloor\)表示向下取整。

參考代碼1

import math
n=int(input())
# num_of_digits 表示位數
num_of_digits = math.floor((math.log2(n))) + 1
# 用對應的權值分別求出0和1,最高位為2^(位數-1),最低位為2^0
for i in range(num_of_digits-1,-1,-1):
    # 當前位所對應的權值為2^i
    current_digit = n // (2**i)
    print(current_digit,end="")
    # 求完之后減去當前位影響
    n -=  current_digit * (2**i)

6882: 十進制轉二進制提供了一種更為簡潔的方法,我們可以將其%2獲得當前位,然后//2拋棄當前位,直到0為止。
100/2 = 50···0
50 / 2 = 25···0
25 / 2 = 12···1
12 / 2 = 6···0
3 / 2 = 1···1
1 / 2 = 0···1
將所得的余數倒過來即得到答案1100100,如下圖所示。

直到0為止也就是while語句,我們可以寫出如下代碼:
參考代碼2

n=int(input())
# n_base_2 代表2進制數,初始為空
n_base_2 = ''
# 直到n為0結束
while n:
    # n%2獲得當前位,為int,需要轉換為str字符串
    # 先求出低位,最后求得高位。所以是當前位+之前求的
    n_base_2 = str(n%2) + n_base_2
    # 拋棄當前位
    n = n // 2

print(n_base_2)

先求出的是低位,最后是高位,也就是先進后出的關系。滿足選修一第三章“棧”的性質,所以也可以用棧去完成。
參考代碼3

st = [-1]*100
# top代表頂端的位置,初始沒有值,所以頂端不存在為-1
top = -1
n = int(input())
# 直到0結束
while n:
    # 要放在棧頂,棧元素個數+1
    top = top+1
    # 當前位進棧
    st[top] = n % 2
    # 拋棄當前位
    n = n//2
# 按照棧從后往前輸出
while top >= 0:
    print(st[top], end="")
    top = top-1

Python的format函數非常強大,存在更簡單的寫法。

參考代碼4
n=int(input())
print(format(n,'b'))

五、二進制轉十進制

6883: 二進制轉十進制 給定二進制數,讓我們轉10進制。
第1位索引 i 為0,其對應為\(2^{位數-1}\),也就是\(2^{n-1-i}\),每一位依次累加即可。
參考代碼1

s = input()
# n存儲結果
n = 0
# 求出長度
l = len(s)
# 對每一位分別進行處理
for i in range(l):
    # s[i]為當前位,類型為str,注意轉換
    n += int(s[i])*2**(l-1-i)
print(n)

當然還存在其他做法,我們從前到后依次處理,每次都將上次得到的結果乘2+當前位,這樣正好每一位乘上的位權是正確的。
參考代碼2

s = input()
# n存儲十進制數
n = 0
# 對每一位分別進行處理
# 由於和索引無關,可以直接遍歷字符串
for i in s:
    # 把上次結果*2+當前位
    n = n * 2 + int(i)
print(n)

Python的int函數自帶進制的處理,直接利用代碼很短

參考代碼4
n = int(input(),2)
print(n)

六、十六進制

二進制數在實際使用中,由於位數太長,不便於書寫和記憶,所以人們常采用十六進制數來表示。
十六進制數的特點是

  1. 由十六個基本數碼組成,即0,1,2,…,9,A,B,C,D,E,F
  2. 采用逢十六進一的進位規則。

十六進制用字母H標識,\(\rm{B574H=11×16^3+5×16^2+7×16^1+4×16^0}\)。與二進制相類似,\(16^3,16^2,16^1,16^0\)是不同位置上的權值。

七、十六進制和其他進制轉換

十進制和十六進制之間關系

十進制 十六進制 十進制 十六進制
0 0 8 8
1 1 9 9
2 2 10 A
3 3 11 B
4 4 12 C
5 5 13 D
6 6 14 E
7 7 15 F

7031: 十進制轉十六進制。求10進制數的每一位我們用了%10得到當前位,//10拋棄當前當前位,不斷進行直到0為止。十進制轉二進制也是這樣,十六進制當然也同理,換為16就可以了,不過10~15還是需要我們特殊處理下。
參考代碼1

n=int(input())
# n_base_2 代表2進制數,初始為空
n_base_16 = ''
# 直到n為0結束
while n:
    # n%16獲得當前位,為int,需要轉換為str字符串
    # 先求出低位,最后求得高位。所以是當前位+之前求的
    if n%16>=10:
        # 求出其距離'A'的值,使用chr函數轉換過去
        n_base_16 = chr(ord('A')+n%16-10) + n_base_16
    else:
        # 不變
        n_base_16 = str(n%16) + n_base_16
    # 拋棄當前位
    n = n // 16

print(n_base_16)

上面的代碼卻錯了,為什么呢,因為數據包含了0,但是我們程序不能對0進行處理,所以需要將其特判掉。

if n==0:
    n_base_16 = '0'

當然我們也可以提前建好索引表。
參考代碼

n=int(input())
base_16_table = "0123456789ABCDEF"
# n_base_2 代表2進制數,初始為空
n_base_16 = ''
if n==0:
    n_base_16 = '0'
# 直到n為0結束
while n:
    # n%16獲得當前位,為int,直接利用索引表找到對應字母
    # 先求出低位,最后求得高位。所以是當前位+之前求的
    n_base_16 = base_16_table[n%16] + n_base_16
    # 拋棄當前位
    n = n // 16

print(n_base_16)

7284: 十六進制轉十進制 與二進制轉十進制同理。
可以嘗試下以下題目
7207: 二進制轉十六進制 我們可以將二進制數先轉換為十進制,再將其轉換為十六進制。也可以從后往前,四位一組將其轉換為十六進制的一位,余下的單獨算。
7285: 十六進制轉二進制我們可以把十六進制的每一位單獨轉換,但是第一位要去除前導0,其他不能去,模擬起來要判斷一下,可以嘗試一下。也可以把十進制當作中間進制進行轉換。

*八、任意進制轉換

可以先嘗試下以下題目
7030: 十進制轉八進制7019: 二進制轉八進制簡易版1386: 十轉換轉R進制
1386: 十轉換轉R進制 涉及讀到文件末尾結束和一行多個數字,可以參照以下讀入方式。
1386讀入參考代碼

# 捕捉異常,讀取不到就結束
try:
    while True:
        # split對字符串分割,然后轉為int對應給n和r
        n, r = map(int, input().split())
        ### 你的代碼
except:
    pass

6198: Alice與進制轉換進階版
給定R1進制的n讓我們轉換為r2進制的,我們需要以十進制作為中間進制,先轉為十進制,最后再轉回r2進制。

參考代碼
base_16_table = "0123456789ABCDEF"
def convert_to_base_10(n_base_r1,r1):
    num = 0
    if n_base_r1[0] == '-':
        # 是負數,把負號去除,結果乘上-1即可
        sign = -1
        n_base_r1 = n_base_r1[1:]
    else:
        sign = 1
    for i in n_base_r1:
        # find函數可以找到出現i的下標
        num = num * r1 + base_16_table.find(i)
    return sign * num
def convert_to_base_r2(n,r2):
    if n<0:
        # 記下符號,將其當正數處理
        sign = -1
        n = -n
    else:
        sign = 1
    n_base_r2 = ''
    # 0特別處理
    if n == 0: 
        n_base_r2 = '0'
    while n:
        n_base_r2 = base_16_table[n%r2] + n_base_r2
        n = n // r2
    if sign == -1:
        return  '-'+n_base_r2
    return n_base_r2
# 捕捉異常,讀取不到就結束
try:
    while True:
        # split對字符串分割,然后轉為int對應給n和r
        n_base_r1, r1, r2 = map(str, input().split())
        # 把r1進制的n轉換為十進制的
        n = convert_to_base_10(n_base_r1,int(r1))
        # 把十進制的n轉換為r2進制的
        n_base_r2 = convert_to_base_r2(n,int(r2))
        print(n_base_r2)
except:
    pass


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM