第六章 組合數(shù)據(jù)類型
組合數(shù)據(jù)類型概述
計算機不僅對單個變量表示的數(shù)據(jù)進行處理冈绊,更多情況蛉谜,計算機需要對一組數(shù)據(jù)進行批量處理。一些例子包括:
- 給定一組單詞{python, data, function, list, loop}寓涨,計算并輸出每個單詞的長度宗兼;
- 給定一個學院學生信息,統(tǒng)計一下男女生比例蜕窿;
- 一次實驗產(chǎn)生了很多組數(shù)據(jù)谋逻,對這些大量數(shù)據(jù)進行分析;
組合數(shù)據(jù)類型能夠將多個同類型或不同類型的數(shù)據(jù)組織起來桐经,通過單一的表示使數(shù)據(jù)操作更有序更容易毁兆。根據(jù)數(shù)據(jù)之間的關系,組合數(shù)據(jù)類型可以分為三類:
序列類型次询、集合類型和映射類型荧恍。 - 序列類型是一個元素向量,元素之間存在先后關系屯吊,通過序號訪問送巡,元素之間不排他。
- 集合類型是一個元素集合盒卸,元素之間無序骗爆,相同元素在集合中唯一存在。
- 映射類型是“鍵-值”數(shù)據(jù)項的組合蔽介,每個元素是一個鍵值對摘投,表示為(key, value)。
序列類型
序列類型是一維元素向量虹蓄,元素之間存在先后關系犀呼,通過序號訪問。
當需要訪問序列中某特定值時薇组,只需要通過下標標出即可外臂。
序列類型支持成員關系操作符(in)、長度計算函數(shù)(len())律胀、分片([])宋光,元素本身也可以是序列類型貌矿。
Python語言中有很多數(shù)據(jù)類型都是序列類型,其中比較重要的是:str(字符串)罪佳、tuple(元組)和list(列表)逛漫。
- 元組是包含0個或多個數(shù)據(jù)項的不可變序列類型。元組生成后是固定的赘艳,其中任何數(shù)據(jù)項不能替換或刪除酌毡。
- 列表則是一個可以修改數(shù)據(jù)項的序列類型,使用也最靈活
元組(tuple)是序列類型中比較特殊的類型蕾管,因為它一旦創(chuàng)建就不能被修改阔馋。元組類型在表達固定數(shù)據(jù)項、函數(shù)多返回值娇掏、多變量同步賦值、循環(huán)遍歷等情況下十分有用勋眯。Python中元組采用逗號和圓括號(可選)來表示婴梧。
#需要打印所有變量(而不只是最后一個)
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
creature = "cat", "dog", "tiger", "human"
creature
color = ("red", 0x001100, "blue", creature)
color
color[2]
color[-1][2]
('cat', 'dog', 'tiger', 'human')
('red', 4352, 'blue', ('cat', 'dog', 'tiger', 'human'))
'blue'
'tiger'
def func(x): #函數(shù)多返回值
return x, x**3
func(3)
a, b = 'dog', 'tiger' #多變量同步賦值
a, b = (b, a) #多變量同步賦值,括號可省略
print(a,b)
import math
for x, y in ((1,0), (2,5), (3,8)): #循環(huán)遍歷
print(math.hypot(x,y)) #求多個坐標值到原點的距離
(3, 27)
tiger dog
1.0
5.385164807134504
8.54400374531753
集合類型
集合類型與數(shù)學中集合的概念一致客蹋,即包含0個或多個數(shù)據(jù)項的無序組合塞蹭。集合中元素不可重復,元素類型只能是固定數(shù)據(jù)類型讶坯,例如:整數(shù)番电、浮點數(shù)、字符串辆琅、元組等漱办,列表、字典和集合類型本身都是可變數(shù)據(jù)類型婉烟,不能作為集合的元素出現(xiàn)娩井。
由于集合是無序組合,它沒有索引和位置的概念似袁,不能分片洞辣,集合中元素可以動態(tài)增加或刪除。集合用大括號({})表示昙衅,可以用賦值語句生成一個集合扬霜。
S = {425, "BIT", (10, "CS"), 424}
S
T = {425, "BIT", (10, "CS"), 424, 425, "BIT"}
T
{424, 425, (10, 'CS'), 'BIT'}
{424, 425, (10, 'CS'), 'BIT'}
由于集合元素是無序的,集合的打印效果與定義順序可以不一致而涉。由于集合元素獨一無二著瓶,使用集合類型能夠過濾掉重復元素。set(x)函數(shù)可以用于生成集合婴谱。
W = set('apple')
W #自動按字母序排列
V = set(("cat", "dog", "tiger", "human"))
V
{'a', 'e', 'l', 'p'}
{'cat', 'dog', 'human', 'tiger'}
集合類型的4種基本操作蟹但,交集(&)躯泰、并集(|)、差集(-)华糖、補集(^)麦向,操作邏輯與數(shù)學定義相同
集合類型主要用于三個場景:成員關系測試、元素去重和刪除數(shù)據(jù)項
"BIT" in {"PYTHON", "BIT", 123, "GOOD"} #成員關系測試
tup = ("PYTHON", "BIT", 123, "GOOD", 123) #元素去重
set(tup)
newtup = tuple(set(tup)-{'PYTHON'}) # 去重同時刪除數(shù)據(jù)項
newtup
True
{'PYTHON', 123, 'GOOD', 'BIT'}
(123, 'GOOD', 'BIT')
集合類型與其他類型最大的不同在于它不包含重復元素客叉,因此诵竭,當需要對一維數(shù)據(jù)進行去重或進行數(shù)據(jù)重復處理時,一般通過集合來完成兼搏。
映射類型
映射類型是“鍵-值”數(shù)據(jù)項的組合卵慰,每個元素是一個鍵值對,即元素是(key, value)佛呻,元素之間是無序的裳朋。鍵值對(key, value)是一種二元關系。在Python中吓著,映射類型主要以字典(dict)體現(xiàn)鲤嫡。
dic = {'name':'張三','age':20}
dic
dic['name']
{'age': 20, 'name': '張三'}
'張三'
列表類型和操作
列表類型的概念
列表(list)是包含0個或多個對象引用的有序序列,屬于序列類型绑莺。與元組不同暖眼,列表的長度和內容都是可變的,可自由對列表中數(shù)據(jù)項進行增加纺裁、刪除或替換诫肠。列表沒有長度限制,元素類型可以不同欺缘,使用非常靈活栋豫。
由于列表屬于序列類型,所以列表也支持成員關系操作符(in)浪南、長度計算函數(shù)(len())笼才、分片([])。列表可以同時使用正向遞增序號和反向遞減序號络凿,可以采用標準的比較操作符(<骡送、<=、==絮记、!=摔踱、>=、>)進行比較怨愤,列表的比較實際上是單個數(shù)據(jù)項的逐個比較派敷。
列表用中括號([])表示,也可以通過list()函數(shù)將元組或字符串轉化成列表。直接使用list()函數(shù)會返回一個空列表篮愉。
ls = [425, "BIT", [10, "CS"], 425]
ls
ls[2][-1][0]
'C'
list((425, "BIT", [10, "CS"], 425))
list("中國是一個偉大的國家")
list()
[425, 'BIT', [10, 'CS'], 425]
'C'
'C'
[425, 'BIT', [10, 'CS'], 425]
['中', '國', '是', '一', '個', '偉', '大', '的', '國', '家']
[]
與整數(shù)和字符串不同腐芍,列表要處理一組數(shù)據(jù),因此试躏,列表必須通過顯式的數(shù)據(jù)賦值才能生成猪勇,簡單將一個列表賦值給另一個列表不會生成新的列表對象。
ls = [425, "BIT", 1024] #用數(shù)據(jù)賦值產(chǎn)生列表ls
lt = ls #lt是ls所對應數(shù)據(jù)的引用颠蕴,lt并不包含真實數(shù)據(jù)
ls[0] = 0
lt
[0, 'BIT', 1024]
列表類型的操作
vlist = list(range(5))
vlist
len(vlist[2:]) #計算從第3個位置開始到結尾的子串長度
2 in vlist #判斷2是否在列表vlist中
vlist[3]="python" #修改序號3的元素值和類型
vlist
vlist[1:3]=["bit", "computer"]
vlist
[0, 1, 2, 3, 4]
3
True
[0, 1, 2, 'python', 4]
[0, 'bit', 'computer', 'python', 4]
與元組一樣泣刹,列表可以通過for…in語句對其元素進行遍歷,基本語法結構如下:
for <任意變量名> in <列表名>:
語句塊
for e in vlist:
print(e, end=" ")
0 bit computer python 4
列表是一個十分靈活的數(shù)據(jù)結構犀被,它具有處理任意長度椅您、混合類型的能力,并提供了豐富的基礎操作符和方法寡键。當程序需要使用組合數(shù)據(jù)類型管理批量數(shù)據(jù)時掀泳,請盡量使用列表類型。
基本統(tǒng)計值計算
以最簡單的統(tǒng)計問題為例西轩,求解一組不定長數(shù)據(jù)的基本統(tǒng)計值开伏,即平均值、標準差遭商、中位數(shù)。
由于平均數(shù)捅伤、標準差和中位數(shù)是三個不同的計算目標劫流,使用函數(shù)方式編寫計算程序。
getNum()函數(shù)從用戶輸入獲得數(shù)據(jù)
mean()函數(shù)計算平均值
dev()函數(shù)計算標準差
median()函數(shù)計算中位數(shù)
from math import sqrt
def getNum(): #獲取用戶輸入
nums = []
iNumStr = input("請輸入數(shù)字(直接輸入回車退出): ")
while iNumStr != "":
nums.append(eval(iNumStr))
iNumStr = input("請輸入數(shù)字(直接輸入回車退出): ")
return nums
def mean(numbers): #計算平均值
s = 0.0
for num in numbers:
s = s + num
return s / len(numbers)
def dev(numbers, mean): #計算方差
sdev = 0.0
for num in numbers:
sdev = sdev + (num - mean)**2
return sqrt(sdev / (len(numbers)-1))
def median(numbers): #計算中位數(shù)
sorted(numbers)
size = len(numbers)
if size % 2 == 0:
med = (numbers[size//2-1] + numbers[size//2])/2
else:
med = numbers[size//2]
return med
n = getNum() #主體函數(shù)
m = mean(n)
print("平均值:{},方差:{:.2},中位數(shù):{}.".format(m,dev(n,m),median(n)))
請輸入數(shù)字(直接輸入回車退出): 98
請輸入數(shù)字(直接輸入回車退出): 97
請輸入數(shù)字(直接輸入回車退出): 96
請輸入數(shù)字(直接輸入回車退出): 99
請輸入數(shù)字(直接輸入回車退出): 95
請輸入數(shù)字(直接輸入回車退出):
平均值:97.0,方差:1.6,中位數(shù):96.
程序先后調用getNum()丛忆、mean()祠汇、dev()和median()函數(shù)。利用函數(shù)的模塊化設計能夠復用代碼并增加代碼的可讀性熄诡。每個函數(shù)內部都采用了簡單的語句可很。
列表在實現(xiàn)基本數(shù)據(jù)統(tǒng)計時發(fā)揮了重要作用,表現(xiàn)在:
- 列表是一個動態(tài)長度的數(shù)據(jù)結構凰浮,可以根據(jù)需求增加或減少元素我抠;
- 列表的一系列方法或操作符為計算提供了簡單的元素運算手段;
- 列表提供了對每個元素的簡單訪問方式及所有元素的遍歷方式袜茧。
字典類型的計算
字典類型的基本概念
通過任意鍵信息查找一組數(shù)據(jù)中值信息的過程叫映射菜拓,Python語言中通過字典實現(xiàn)映射。Python語言中的字典可以通過大括號({})建立笛厦,建立模式如下:
{<鍵1>:<值1>, <鍵2>:<值2>, … , <鍵n>:<值n>}
其中纳鼎,鍵和值通過冒號連接,不同鍵值對通過逗號隔開。
Dcountry={"中國":"北京", "美國":"華盛頓", "法國":"巴黎"}
print(Dcountry)
{'中國': '北京', '美國': '華盛頓', '法國': '巴黎'}
字典打印出來的順序與創(chuàng)建之初的順序不同贱鄙,這不是錯誤劝贸。字典是集合類型的延續(xù),各個元素并沒有順序之分逗宁。
字典最主要的用法是查找與特定鍵相對應的值映九,這通過索引符號來實現(xiàn)。
Dcountry["中國"]
'北京'
一般來說疙剑,字典中鍵值對的訪問模式如下氯迂,采用中括號格式:
<值> = <字典變量>[<鍵>]
字典中對某個鍵值的修改可以通過中括號的訪問和賦值實現(xiàn):
Dcountry["中國"]='大北京'
Dcountry
{'中國': '大北京', '法國': '巴黎', '美國': '華盛頓'}
字典類型的操作
#通過中括號可以增加新的元素
Dcountry={"中國":"北京", "美國":"華盛頓", "法國":"巴黎"}
Dcountry["英國"]="倫敦"
print(Dcountry)
#直接使用大括號({})可以創(chuàng)建一個空的字典,并通過中括號([])向其增加元素
Dp={}
Dp['2^10']=1024
Dp
{'中國': '北京', '美國': '華盛頓', '法國': '巴黎', '英國': '倫敦'}
{'2^10': 1024}
字典類型的函數(shù)和方法舉例:
Dcountry={"中國":"北京", "美國":"華盛頓", "法國":"巴黎"}
Dcountry.keys()
list(Dcountry.values())
Dcountry.items()
'中國' in Dcountry #只對鍵進行判斷
Dcountry.get('美國', '悉尼') #'美國'在字典中存在
Dcountry.get('澳大利亞', '悉尼') #'澳大利亞'在字典中不存在
dict_keys(['中國', '美國', '法國'])
['北京', '華盛頓', '巴黎']
dict_items([('中國', '北京'), ('美國', '華盛頓'), ('法國', '巴黎')])
True
'華盛頓'
'悉尼'
與其他組合類型一樣言缤,字典可以通過for…in語句對其元素進行遍歷嚼蚀,基本語法結構如下:
for <變量名> in <字典名>:
語句塊
for key in Dcountry:
print(key)
中國
美國
法國
字典是實現(xiàn)鍵值對映射的數(shù)據(jù)結構,請理解如下基本原則:
- 字典是一個鍵值對的集合管挟,該集合以鍵為索引轿曙,一個鍵信息只對應一個值信息;
- 字典中元素以鍵信息為索引訪問僻孝;
- 字典長度是可變的导帝,可以通過對鍵信息賦值實現(xiàn)增加或修改鍵值對。
jieba庫的使用
jieba庫的概述
jieba是Python中一個重要的第三方中文分詞函數(shù)庫
jieba庫是第三方庫穿铆,不是安裝包自帶您单,需要通過pip指令安裝
pip install jieba # 或者 pip3 install jieba
import jieba
jieba.lcut("中國是一個偉大的國家")
Building prefix dict from the default dictionary ...
Dumping model to file cache F:\Temp\jieba.cache
Loading model cost 2.958 seconds.
Prefix dict has been built succesfully.
['中國', '是', '一個', '偉大', '的', '國家']
jieba庫的解析
import jieba
jieba.lcut("中華人民共和國是一個偉大的國家")
jieba.lcut("中華人民共和國是一個偉大的國家", cut_all=True)
jieba.lcut_for_search("中華人民共和國是一個偉大的國家")
['中華人民共和國', '是', '一個', '偉大', '的', '國家']
['中華',
'中華人民',
'中華人民共和國',
'華人',
'人民',
'人民共和國',
'共和',
'共和國',
'國是',
'一個',
'偉大',
'的',
'國家']
['中華', '華人', '人民', '共和', '共和國', '中華人民共和國', '是', '一個', '偉大', '的', '國家']
文本詞頻統(tǒng)計
《Hamlet》英文詞頻統(tǒng)計
def getText():
txt = open("f:/code/python/Hamlet.txt", "r",encoding='utf8').read()
txt = txt.lower()
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~':
txt = txt.replace(ch," ") #將文本中特殊字符替換為空格
return txt
hamletTxt = getText()
words = hamletTxt.split()
counts = {}
for word in words:
counts[word] = counts.get(word,0) + 1
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(10):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
the 1137
and 965
to 754
of 667
you 550
a 542
i 541
my 514
hamlet 461
in 436
觀察輸出結果可以看到,高頻單詞大多數(shù)是冠詞荞雏、代詞虐秦、連接詞等語法型詞匯,并不能代表文章的含義凤优。進一步悦陋,可以采用集合類型構建一個排除詞匯庫excludes,在輸出結果中排除這個詞匯庫中內容筑辨。
excludes = {"the","and","of","you","a","i","my","in","it","his","not","is","to","that","this","for","your","me","but","be","as","he","him","what"}
def getText():
txt = open("f:/code/python/Hamlet.txt", "r", encoding='utf8').read()
txt = txt.lower()
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~':
txt = txt.replace(ch, " ") #將文本中特殊字符替換為空格
return txt
hamletTxt = getText()
words = hamletTxt.split()
counts = {}
for word in words:
counts[word] = counts.get(word,0) + 1
for word in excludes:
del(counts[word])
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(10):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
hamlet 461
lord 309
with 268
so 197
king 194
have 181
will 169
horatio 157
do 151
no 142
《三國演義》人物出場統(tǒng)計
import jieba
txt = open("f:/code/Python/三國演義.txt", "r", encoding='utf8').read()
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1: #排除單個字符的分詞結果
continue
else:
counts[word] = counts.get(word,0) + 1
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(15):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
曹操 936
孔明 831
將軍 772
卻說 656
玄德 570
關公 509
丞相 491
二人 466
不可 441
荊州 421
不能 387
孔明曰 385
玄德曰 383
如此 378
張飛 348
觀察輸出結果俺驶,同一個人物會有不同的名字,這種情況需要整合處理棍辕。同時暮现,與英文詞頻統(tǒng)計類似,需要排除一些人名無關詞匯楚昭,如“卻說”送矩、“將軍”等。
import jieba
excludes = {"將軍","卻說","荊州","二人","不可","不能","如此"}
txt = open("f:/code/Python/三國演義.txt", "r", encoding='utf8').read()
words = jieba.lcut(txt)
counts = {}
for word in words:
if len(word) == 1:
continue
elif word == "諸葛亮" or word == "孔明曰":
rword = "孔明"
elif word == "關公" or word == "云長":
rword = "關羽"
elif word == "玄德" or word == "玄德曰":
rword = "劉備"
elif word == "孟德" or word == "丞相":
rword = "曹操"
else:
rword = word
counts[rword] = counts.get(rword,0) + 1
for word in excludes:
del(counts[word])
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(5):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
曹操 1434
孔明 1373
劉備 1224
關羽 779
張飛 348
請繼續(xù)完善程序哪替,排除更多無關詞匯干擾肾请,總結出場最多的20個人物都有哪些。這里贫母,給出參考答案弊仪。
曹操(1451)、孔明(1383)、劉備(1252)、關羽(784)、張飛(358)呼伸、
呂布(300)、趙云(278)钝尸、孫權(264)括享、司馬懿(221)、周瑜(217)珍促、
袁紹(191)铃辖、馬超(185)、魏延(180)猪叙、黃忠(168)娇斩、姜維(151)、
馬岱(127)穴翩、龐德(122)犬第、孟獲(122)、劉表(120)芒帕、夏侯惇(116)
Python之禪
什么樣的程序是好的歉嗓?如何編寫漂亮的代碼?這都是學習編程一段時間最經(jīng)常提出的問題背蟆,卻最難回答遥椿。程序設計語言如同自然語言,好的代碼就像文學作品淆储,不僅達意,更要優(yōu)美家浇。那什么是“好”本砰?什么是“優(yōu)美”?領悟編程代碼優(yōu)美的過程類似參禪钢悲,除了不斷練習点额,也需要理解一些原則。
Python編譯器以函數(shù)庫的形式內置了一個有趣的文件莺琳,被稱為“Python之禪”(The Zen of Python)还棱。當調用如下一行語句后,會出現(xiàn)一段有趣的運行結果惭等。
import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Python之禪 作者:Tim Peters
優(yōu)美勝于丑陋
明了勝于隱晦
簡潔勝于復雜
復雜勝于凌亂
扁平勝于嵌套
間隔勝于緊湊
可讀性很重要
即便假借特例的實用性之名珍手,也不要違背上述規(guī)則
除非你確定需要,任何錯誤都應該有應對
當存在多種可能,不要嘗試去猜測
只要你不是Guido琳要,對于問題盡量找一種寡具,最好是唯一明顯的解決方案
做也許好過不做,但不假思索就動手還不如不做
如果你無法向人描述你的實現(xiàn)方案稚补,那肯定不是一個好方案
如果實現(xiàn)方案容易解釋童叠,可能是個好方案
命名空間是絕妙的理念,要多運用
除了Python之禪所表達的Python設計理念课幕,該程序還有另一段魅力:
s = """
Gur Mra bs Clguba, ol Gvz Crgref
Ornhgvshy vf orggre guna htyl.
Rkcyvpvg vf orggre guna vzcyvpvg.
Fvzcyr vf orggre guna pbzcyrk.
Pbzcyrk vf orggre guna pbzcyvpngrq.
Syng vf orggre guna arfgrq.
Fcnefr vf orggre guna qrafr.
Ernqnovyvgl pbhagf.
Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
Nygubhtu cenpgvpnyvgl orngf chevgl.
Reebef fubhyq arire cnff fvyragyl.
Hayrff rkcyvpvgyl fvyraprq.
Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
Abj vf orggre guna arire.
Nygubhtu arire vf bsgra orggre guna *evtug* abj.
Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!
"""
d = {}
for c in (65, 97):
for i in range(26):
d[chr(i+c)] = chr((i+13) % 26 + c)
print("".join([d.get(c, c) for c in s]))
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
密文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
原文:N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
密文:a b c d e f g h i j k l m n o p q r s t u v w x y z
原文:n o p q r s t u v w x y z a b c d e f g h i j k l m
這個算法可以看作是凱撒密碼的一種擴展厦坛,相比凱撒密碼,采用循環(huán)移動13個位置乍惊,加密和解密可以用同一個程序杜秸。
練習題