在计算机科学与技术的学习旅程中,掌握编程技能是不可或缺的一环。计算机二级考试作为衡量学生计算机基础知识和实践能力的重要标尺,其中的简单编程题部分尤为关键。这些题目不仅考察了考生对编程语言语法的掌握程度,还检验了考生解决实际问题的能力以及逻辑思维和代码组织能力。
“简单编程题(代码完善)”作为本系列笔记的第二部分,旨在通过一系列精心设计的题目和解析,帮助考生深入理解编程的精髓,学会如何在给定框架或提示下,快速准确地完善代码,实现特定功能。与纯粹的编程练习不同,代码完善题目要求考生具备较高的代码阅读能力和问题分析能力,能够在理解现有代码逻辑的基础上,迅速定位问题所在,并给出恰当的解决方案。在本部分笔记中,我们将通过一系列实例,覆盖不同编程语言中的常见编程任务,如数据处理、算法实现、字符串操作、文件读写等。每个实例都将从题目描述出发,逐步引导考生分析题目要求,梳理解题思路,并最终给出完善的代码示例。同时,我们还会对代码中的关键点和易错点进行详细解析,帮助考生避免常见错误,提高编程效率和质量。最后,“计算机二级笔记(二)——简单编程题(代码完善)”旨在通过系统、全面的学习和训练,帮助考生掌握编程技能,提升编程能力,为顺利通过计算机二级考试及未来的学习和工作奠定坚实的基础。让我们携手并进,在编程的世界里不断探索和前行!
一、涉及计算的简单编程
例题1:键盘输入一组人员的姓名、性别、年龄等信息,信息间采用空格分隔,每人一行,空行回车结束录入,示例格式如下
张三 男 23
李四 女 21
王五 男 18
计算并输出这组人员的平均年龄(保留2位小数)和其中男性人数,格式如下:
平均年龄是20.67 男性人数是2
题目提供的原始代码为:
# 以下代码为提示框架
# 请在...处使用一行或多行代码替换
# 请在______处使用一行代码替换
# 注意:提示框架代码可以任意修改,以完成程序功能为准
data = input() # 姓名 年龄 性别
...
while data:
...
data = input()
...
print("平均年龄是{:.2f} 男性人数是{}".format(______))
这段代码的目的是从用户输入中统计一组人的平均年龄和男性人数。用户首先输入一行包含姓名、性别和年龄的字符串(用空格分隔),然后可以选择继续输入更多这样的行,直到不再输入任何内容(即输入为空时停止)。下面是代码的详细解释:
- 初始化变量:
s=0
:初始化年龄总和为0。n=0
:初始化男性人数为0。i=0
:初始化人数计数器为0,用于记录输入了多少行数据。- 循环读取用户输入:
- 使用
while data:
循环来持续读取用户输入,直到用户输入为空(即按下回车键而不输入任何内容)。- 在循环内部,首先通过
i=i+1
增加人数计数器。- 使用
ls=data.split()
将输入的字符串按空格分割成列表,假设每个输入都严格遵循“姓名 性别 年龄”的格式。- 处理数据:
s=s+int(ls[2])
:将当前行的年龄(ls[2]
)转换为整数并累加到年龄总和s
中。if ls[1]=='男':
:检查当前行的性别是否为“男”。如果是,则通过n=n+1
增加男性人数计数器。- 计算平均年龄:
- 在所有输入处理完毕后,通过
s=s/i
计算平均年龄,其中s
是所有人的年龄总和,i
是输入的总行数(即总人数)。- 输出结果:
- 使用
print("平均年龄是{:.2f} 男性人数是{}".format(s,n))
输出平均年龄(保留两位小数)和男性人数。
经过以上的分析,将代码修改如下:
# 以下代码为提示框架
# 请在...处使用一行或多行代码替换
# 请在______处使用一行代码替换
# 注意:提示框架代码可以任意修改,以完成程序功能为准
data = input() # 姓名 性别 年龄
s=0
n=0
i=0
while data:
i=i+1
ls=data.split()
s=s+int(ls[2])
if ls[1]=='男':
n=n+1
data = input()
s=s/i
print("平均年龄是{:.2f} 男性人数是{}".format(s,n))
二、涉及排序的简单编程
例题2:键盘输入一组我国高校所对应的学校类型,以空格分隔,共一行,示例格式如下:综合 理工 综合 综合 综合 师范 理工 统计各类型的数量,从数量多到少的顺序屏幕输出类型及对应数量,以英文冒号分隔,每个类型一行,输出参考格式如下:
综合:4
理工:2
师范:1
题目提供的原始代码为:
# 以下代码为提示框架
# 请在...处使用一行或多行代码替换
# 请在______处使用一行代码替换
# 注意:提示框架代码可以任意修改,以完成程序功能为准
txt = input("请输入类型序列: ")
...
d = {}
...
ls = list(d.items())
ls.sort(key=lambda x:x[1], reverse=True) # 按照数量排序
for k in ls:
print("{}:{}".format(k[0], k[1]))
这段代码的主要功能是统计用户输入的字符串(假设是由空格分隔的多个类型序列)中每个元素的出现次数,并按照出现次数从多到少排序,最后打印出排序后的结果。下面是代码的详细解释:
- 输入处理:
- 使用
input("请输入类型序列: ")
获取用户输入的字符串,并将其存储在变量txt
中。- 使用
t=txt.split()
将输入的字符串txt
按空格分割成一个列表t
,列表中的每个元素都是原字符串中的一个“类型”或“项目”。- 统计次数:
- 初始化一个空字典
d
,用于存储每个类型及其对应的出现次数。- 遍历列表
t
中的每个元素t[i]
,使用d[t[i]]=d.get(t[i],0)+1
统计每个元素的出现次数。这里d.get(t[i],0)
尝试获取键t[i]
对应的值,如果不存在则默认为0,然后加1表示出现了一次。- 排序:
- 将字典
d
的项(即键值对)转换为列表ls
,每个元素是一个元组,形如(key, value)
。- 使用
ls.sort(key=lambda x:x[1], reverse=True)
对列表ls
进行排序。这里使用了lambda
函数作为key
参数,指定排序的依据是元组的第二个元素(即值或出现次数),reverse=True
表示降序排序,即从大到小。- 打印结果:
- 遍历排序后的列表
ls
,使用print("{}:{}".format(k[0], k[1]))
打印每个元素的名称(键)和对应的出现次数(值)。
经过以上的分析,将代码修改如下:
# 以下代码为提示框架
# 请在...处使用一行或多行代码替换
# 请在______处使用一行代码替换
# 注意:提示框架代码可以任意修改,以完成程序功能为准
txt = input("请输入类型序列: ")
t=txt.split()
d = {}
for i in range(len(t)):
d[t[i]]=d.get(t[i],0)+1
ls = list(d.items())
ls.sort(key=lambda x:x[1], reverse=True) # 按照数量排序
for k in ls:
print("{}:{}".format(k[0], k[1]))
三、涉及文件读写的简单编程
例题3:某村有40名有选举权和被选举权村民,名单由考生文件夹下文件 name.txt 给出,从这40名村民中选出一人当长,40人的投票信息由考生文件夹下文件 vote.txt 给出,每行是一张选票的信息,有效票中得票最多的村民当选。问题1:请从 vote.txt 中筛选出无效票写入文件vote1.txt 。有效票的含义是:选票中只有一个名字且该名字在 name.txt 文件列表中,不是有效票的票称为无效票。 问题2:给出当选村长的名字及其得票数。
题目提供的原始代码为:
f=open("name.txt")
names=f.readlines()
f.close()
f=open("vote.txt")
votes=f.readlines()
f.close()
f.close()
f=open("vote1.txt","w")
D={}
NUM=0
for vote in _______(1)________:
num = len(vote.split())
if num==1 and vote in _______(2)________:
D[vote[:-1]]=_______(3)________+1
NUM+=1
else:
f.write(_______(4)________)
f.close()
l=list(D.items())
l.sort(key=lambda s:s[1],_______(5)________)
name=____(6)____
score=____(7)____
print("有效票数为:{} 当选村长村民为:{},票数为:{}".format(NUM,name,score))
这段代码的目的是从一个名为
vote.txt
的文件中读取投票记录,并与另一个为name.txt
的文件中的村民名单进行比对,以确定哪些投票是有效的(即投票的村民名确实存在于村民名单中),并统计每位有效投票的村民的票数。最后,它将输出获得最多票数的村民的姓名及其票数,以及有效票数的总数。下面是代码的详细解释:
- 打开并读取村民名单:
- 使用
open("name.txt")
打开名为name.txt
的文件,并将文件对象赋值给变量f
。- 使用
f.readlines()
读取文件中的所有行,每行代表一个村民的名字,并将这些行(字符串列表)赋值给变量names
。- 关闭文件
f.close()
。- 打开并读取投票记录:
- 再次使用
open("vote.txt")
打开名为vote.txt
的文件,该文件包含投票记录。- 使用
f.readlines()
读取所有投票记录,并将它们(字符串列表)赋值给变量votes
。- 关闭文件
f.close()
。- 准备写入无效投票记录:
- 使用
open("vote1.txt", "w")
打开(或创建)一个名为vote1.txt
的文件用于写入,设置为写入模式("w")。这意味着如果文件已存在,其内容将被清空。- 处理投票记录:
- 初始化一个空字典
D
用于存储每个有效村民的票数。- 初始化变量
NUM
为 0,用于记录有效票数的总数。- 遍历
votes
列表中的每条投票记录(vote
):(1)使用vote.split()
将投票记录(假设为单个名字后跟可能的空格)按空格分割成列表,并计算列表的长度num
。(2)如果num
等于 1(意味着投票记录仅包含一个名字)且该名字存在于names
列表中,则认为是有效投票:
NUM
加一,记录有效票数。- 从
vote
中去除可能存在的换行符,并使用这个处理过的名字作为键在字典D
中更新票数。- 如果投票记录不符合上述条件(即不是有效投票),则将其写入
vote1.txt
文件。- 关闭
vote1.txt
文件:
- 完成投票处理后,关闭
vote1.txt
文件。- 统计并输出结果:
- 将字典
D
的项(即村民姓名和票数对)转换为列表l
。- 使用
sort()
方法对列表l
进行排序,排序依据是票数(即列表项的第二个元素),并设置reverse=True
以实现降序排序。- 从排序后的列表
l
中取出第一个元素(票数最多的村民),并分别获取其姓名(name
)和票数(score
)。- 输出有效票数的总数、当选村长的村民姓名及其票数。
经过以上的分析,将代码修改如下:
f=open("name.txt")
names=f.readlines()
f.close()
f=open("vote.txt")
votes=f.readlines()
f.close()
f=open("vote1.txt","w")
D={}
NUM=0
for vote in votes:
num = len(vote.split()) #分解成列表,并求列表长度(元素个数)
if num==1 and vote in names: #仅一个且在姓名中,有效
D[vote[:-1]]=D.get(vote[:-1],0)+1
NUM+=1
else:
f.write(vote)
f.close()
l=list(D.items())
l.sort(key=lambda s:s[1],reverse=True)
name=l[0][0]
score=l[0][1]
print("有效票数为:{} 当选村长村民为:{},票数为:{}".format(NUM,name,score))
四、涉及向量内积计算的简单编程
例题4:我们定义了一个6个浮点数的一维列表lt1和一个包含3个数的一维列表lt2。示例如下:
It1=[0.69,0.292,0.33,0.131,0.61.0.254
It2=[0.1,0.8,0.2]
计算lt1列表跟lt2列表的向量内积,两个向量X=[x1,x2,x3]和Y=[y1,y2,y3]的内积计算公式:
k=x1*y1+x2*y2+x3*y3
将每次计算的两组对应元素的值、以及对应元素乘积的累计和(k)的值显示在屏幕上格式如下所示。k=0.069,It2[0]=0.100,lt1[0+0]=0.690
k=0.303,lt2[1]=0.800,lt1[0+1]=0.292
k=0.369,It2[2]=0.200,lt1[0+2]=0.330
........(略)
计算方式如下:
第一步计算第一个k, 分为3次累加计算:
k = lt2[0] * lt1[0+0] ; k = lt2[0] * lt1[0+0] + lt2[1] * lt1[0+1] ;
k = lt2[0] * It1[0+0] + lt2[1] * lt1[0+1] + lt2[2] * lt1[0+2]
最终得到最后一个k值保存
第二步计算第二个k,分为3次累加计算:
k=lt2[0] * lt1[1 +0] ;
k=lt2[0] * lt1[1+0] + lt2[1] * lt1[1 +1] ;
k=lt2[0] * lt1[1+0] + lt2[1] * lt1[1+1] + lt2[2] * lt1[1+2]
最终得到最后一个k值保存,依照此规律依次计算。
题目提供的原始代码为:
#请在.....处填写多行表达式或语句
#不得修改其他代码
img = [0.244, 0.832, 0.903, 0.145, 0.26, 0.452]
filter = [0.1,0.8,0.1]
res = []
for i in range(len(img)-2):
...
res.append(k)
for r in res:
print('{:<10.3f}'.format(r),end = '')
按照题目提供的思路,代码修改如下:
#请在.....处填写多行表达式或语句
#不得修改其他代码
img = [0.244, 0.832, 0.903, 0.145, 0.26, 0.452]
filter = [0.1,0.8,0.1]
res = []
for i in range(len(img)-2):
k=0 #有多个和,所以每次赋初始值0
for j in range(3): #求3次累计和
k+=filter[j]*img[i+j] #求3次累计和
print('k={:.3f},filter[{}]={:.3f},img[{}+{}]={:.3f}'.format(k,j,filter[j],i,j,img[i+j]))
res.append(k)
for r in res:
print('{:<10.3f}'.format(r),end = '')
五、涉及jieba库的简单编程
例题5:用户输入一首诗的文本,包含中文逗号和句号。用 jieba 库的精确模式对输入文本分词。
1.将分词后的词语输出并以"/"分隔并统计中文词语数并输出。
2.以逗号和句号将输入文本分隔成单句并输出,每句一行,每行 20 个字符宽,居中对齐。
在1和 2 的输出之间,增加一个空行,
示例输入:
床前明月光,疑是地上霜。
输出:
床前/明月光/疑是/地上/霜/中文词语数是:5
床前明月光
疑是地上霜
题目提供的原始代码为:
# 在……上补充一行或多行代码
import jieba
s = input("请输入一段中文文本,句子之间以逗号或句号分隔:")
......
for i in slist:
if i in ",。":
continue
......
print("\n中文词语数是:{}\n".format(m))
......
我们使用jieba.lcut
方法对输入的字符串s
进行精确模式分词,分词结果是一个包含所有词汇的列表,赋值给变量slist
。我们初始化计数器为0,检查元素是否为逗号或句号。如果是,则跳出当前循环迭代,否则,计时器加1 。接着初始化一个空字符串word
,用于累积遇到标点符号之前的字符。在循环体内,首先检查当前字符j
是否是中文逗号或中文句号。如果是,那么执行以下操作:使用print("{:^20}".format(word))
打印之前累积的字符串word
,并且该字符串会被居中显示在一个宽度为20的字段中。这里的{:^20}
是字符串格式化的一部分,表示内容将居中,并且总宽度为20个字符。如果word
的长度小于20,那么它会在两边填充空格以达到居中效果。 如果当前字符不是中文逗号或中文句号,那么执行word += j
,即将当前字符添加到word
字符串的末尾。
经过以上的分析,将代码修改如下:
# 在……上补充一行或多行代码
import jieba
s = input("请输入一段中文文本,句子之间以逗号或句号分隔:")
slist = jieba.lcut(s)
m = 0
for i in slist:
if i in ",。":
continue
m+=1
print(i,end="/")
print("\n中文词语数是:{}\n".format(m))
word = ''
for j in s:
if j in ",。":
print("{:^20}".format(word))
word = ""
continue
word+=j
例题6:
(1)获取用户输入的一段文本,包含但不限于中文字符、中文标点符号及其他字符:
(2)用iieba的精确模式分词,统计分词后中文词语词频,县体为:将字符长度大于等于2的词语及其词题写入文件
data2.txt,每行一个词语,词语和词频之间用冒号分隔。
示例如下:
输入:
借助平台优势,宣传推广相应产品,并为技术从业者提供更多学习、交流、探讨的机会,从而促进技术交流、企业互
通、人才培养,促进技术的发展。输出:
借助:1
平台:1
优势:1
宣传:1
推广:1
相应:1
产品:1
技术:3从业者:1
.........(略)
题目提供的原始代码为:
# 在……上补充一行或多行代码
import jieba
……
s = input("请输入一个中文字符串,包含逗号和句号:")
k=jieba.lcut(s)
d1 = {}
for i in k:
……
我们使用jieba.lcut
方法对输入的字符串s
进行中文分词,分词结果是一个列表,每个元素都是一个分词后的词语,这个列表被赋值给变量k
。首先初始化一个空字典d1
用于存储词语及其频次。然后遍历分词结果列表k
中的每个词语i
,如果词语的长度大于等于2,则将该词语作为键添加到字典d1
中,并将对应的值(即频次)增加1。如果词语之前已经存在于字典中,则直接增加其频次;如果不存在,则使用d1.get(i,0)
获取其当前频次(如果不存在则为0),然后加1。接着,我们遍历字典d1
的键(即词语),将每个词语及其对应的频次(转换为字符串)写入到之前打开的文件f
中。每个词语及其频次占一行,词语和频次之间用冒号分隔。
经过以上的分析,将代码修改如下:
# 在……上补充一行或多行代码
import jieba
f = open('data2.txt','w')
s = input("请输入一个中文字符串,包含逗号和句号:")
k=jieba.lcut(s)
d1 = {}
for i in k:
if len(i) >= 2:
d1[i] = d1.get(i,0) + 1
for j in d1:
f.write(j+':'+str(d1[j])+'\n')
f.close()