【2023Python程序设计期末复习】程序填空题题型整理(带解析)

  1. 下面代码的功能是,随机生成50个介于 [1,20] 之间的整数,然后统计每个整数出现频率。请把处缺少的代码补全。

    import random
    x = [random.<!-- 1 -->(1,20) for i in range(<!-- 2 -->)]
    r = dict()
    for i in x:
        r[i] = r.get(i, <!-- 3 -->)+1
    for k, v in r.items():
    	print(k, v)
    
    答案:randint、500
    以下是添加了详细注释的代码以便理解:
    
    import random # 引入随机数函数库
    
    x = [random.<!-- 1 -->(1,20) for i in range(<!-- 2 -->)] 
    # 通过 50 次循环生成列表,每次循环中生成的项目为使用random.randint()函数生成的1-20范围内的随机数
    
    r = dict() # 声明一个空字典备用
    
    for i in x: 
        # 循环遍历生成的列表,用字典的键值对来保存数字及其出现频率
        
        r[i] = r.get(i, <!-- 3 -->)+1 
        # 查询字典内是否存在遍历到的列表元素键,如果存在,则将其的值+1
        # 如果不存在,则新建一个键值对,并将值赋值为1
        #此处的填空为查找不到时的默认值,根据逻辑,
        # 如果找不到的话默认值应该为0,0+1后才能符合不存在时值为1的要求 
        
    for k, v in r.items(): 
    # 通过items函数获取字典内的所有键值对并循环遍历
        
    	print(k, v) # 打印键值对
    
  2. 生成包含 1000 个随机字符的字符串,然后统计前 20 个高频字符,最后以 15 个位左对齐输出高频字符,以 5 个位右对齐输出个数。请把处缺少的代码补全。

    import random
    <!-- 1 -->
    
    x = string.ascii_letters + string.digits + string.punctuation
    y = [<!-- 2 -->for i in range(1000)]
    d = dict()
    for ch in y:
           d[ch] = d.get(ch, 0) + 1    
    items=list(d.items())                   
    items.sort(<!-- 3 -->,reverse=True)  
    for i in range(20):
         word,count = items[i]
         print(<!-- 4 -->%(word,count))
    
    答案:import string、random.choice(x)、key=lambda x:x[1]"%-15s%5d"
    以下是添加了详细注释的代码以便理解:
    import random # 引入随机函数库
    
    <!-- 1 --> 
    # 由于行7使用了string函数库的内容,因此这里缺失了对string库的引用
    
    x = string.ascii_letters + string.digits + string.punctuation 
    # 将字母、数字和标点符号组合成一个字符串,并赋值给变量x
    
    y = [<!-- 2 -->for i in range(1000)] 
    # 使用列表推导式生成列表
    # 根据题意,此时应该随机抽取x这个字符库内的字符,因此此处应该填random.choice(x)
    # 该函数用于从给定的序列中随机选择一个元素
    
    d = dict() #创建一个空字典备用
    
    for ch in y:
       d[ch] = d.get(ch, 0) + 1 
    # 同上题,将出现频率作为键值对保存到字典中
    
    items=list(d.items()) 
    # 由于需要统计频率前20高的字符,因此需要把字典转换为列表来准备排序(字典本身是无序的)
    
    items.sort(<!-- 3 -->,reverse=True) # 通过排序函数来倒序排序
    # 注意此时每个列表内的元素实际上仍然是键值对元组,因此需要重写排序规则
    # 排序规则通过显式指定sort函数的key参数来重写:
    # key=lambda x:x[1] 的意思是通过元组的第二个项目来排序,即键值对的值,也就是频率
    
    for i in range(20): # 遍历输出
         word,count = items[i]
         print(<!-- 4 -->%(word,count)) 
        # 依据题目要求,此时需要控制格式输出,左对齐通过-指定,宽度通过格式字符前的数字指定
        # 因此此处的格式控制字符应为:"%-15s%5d"
    
  3. 用户输入 5 ,打印如下的字符金字塔图形,请把处缺少的代码补全。

    金字塔:
         &
        &&&
       &&&&&
      &&&&&&&
     &&&&&&&&&
    
    n=input('输入行数:')
    <!-- 1 -->
    for i in range(1,n+1):
        print(<!-- 2 -->,end=' ')
        for j in range(1,2*i):
            print('&',<!-- 3 -->)
        print()
    
    答案:n=int(n)' '*(n-i)、end=''
    以下是添加了详细注释的代码以便理解:
    n=input('输入行数:') # 读取用户的输入
    
    <!-- 1 -->
    # input读取的输入会被保存为string,因此在下一步操作前需要将其转换为int
    
    for i in range(1,n+1): # 循环n次,每次打印一行
        
        print(<!-- 2 -->,end=' ') 
        # 打印&符号前的空格,需要依次递减,因此数量是n-i-1,由于end参数存在一个空格,所以空格数量是n-i
        
        for j in range(1,2*i): 
        # 循环打印每一行的&,通过i来控制输出数量
        
            print('&',<!-- 3 -->) 
            # 此时不需要打印多余空格,因此end=''
            
        print() # 换行
    
  4. 质因数分解,如输入60,则得到60 = 2 * 2 * 3 * 5. 请把处缺少的代码补全。

    x=eval(input("请输入小于1000的整数:"))
    k=2
    <!-- 1 -->                     
    while  x>1:
        if <!-- 2 -->:
            print(k,end=" ")
            x = x//k
            if x >1:
                print("*",end=" ")     
        else:
            <!-- 3 -->
    
    答案:print(x,"=",end=" ")、x%k==0、k+=1
    以下是添加了详细注释的代码以便理解:
    x=eval(input("请输入小于1000的整数:")) # 读取输入的同时将x转换为数值类型
    
    k=2
    
    <!-- 1 -->   
    # 根据题意,此处缺少输入数字本身的那个前缀输出,即样例中的60=,因此在此处补上输出
    
    while  x>1: # 如果x仍未被除尽就继续循环
        if <!-- 2 -->: 
        # 根据下文的输出,此处应该是判断x是否可以被k整除
            
            print(k,end=" ") # 可以被整除的话就输出k
            
            x = x//k # 输出后将x整除
            
            if x > 1:  
            # 如果整除后x仍然大于1说明仍然未完全分解,此时应该输出乘号
                print("*",end=" ")     
        else:
            <!-- 3 --> # 如果x不能被k整除,则应该让k递增
    
  5. 验证哥德巴赫猜想:一个大于等于6的偶数可以表示为两个素数之和,请把处缺少的代码补全。

    import math
    x=eval(input("输入一个数"))
    while x<6 or x%2==1: # 大于6的偶数
        x=eval(input("输入一个数"))
    for n1 in<!-- 1 -->:          
    	m1=int(math.sqrt(n1)+1)
        for i in range(2,m1): #2-sqrt(n1)
            if<!-- 2 -->:
                break
        else:
            <!-- 3 -->
            m2=math.ceil(math.sqrt(n2)+1)
            for j in range(2,m2):
                if n2%j==0 and j<n2:
                <!-- 4 -->
            else:
                print(x,'=',n1,'+',n2)
    
    答案:range(3,x//2,2)、n1%i==0、n2=x-n1、break
    以下是添加了详细注释的代码以便理解:
    
    import math # 引入数学函数库
    
    x=eval(input("输入一个数")) # 获取输入的同时将输入转换为数值类型
    
    while x<6 or x%2==1: # 该循环读取语句确保输入的数是大于6的偶数
        x=eval(input("输入一个数"))
        
    for n1 in<!-- 1 -->: # 从3开始遍历素数,遍历到x的一半为止,同时由于素数不可能是偶数所以步长为2
        
    	m1=int(math.sqrt(n1)+1) 
        # 计算n1的平方根并四舍五入加1,将结果转换为整数类型并保存,作为循环结束条件
        
        for i in range(2,m1): 
        #从2到n1的平方根进行遍历
        
            if<!-- 2 -->: 
            # 如果n1能被i整除则跳出循环,说明n1不是素数
                break
                
        else: 
        # 注意这个else不是if的else,而是for的else
        # 表示循环正常退出,即n1是素数的情况
            
            <!-- 3 --> 
            # 根据上下文可知有一个n2没被赋值,此空应该为n2的赋值
            # 根据逻辑此时已发现一个质数,那么接下来应该判断x-n1是否是素数来验证猜想
            
            m2=math.ceil(math.sqrt(n2)+1) 
            # 同样的,计算n1的平方根并四舍五入加1,将结果转换为整数类型并保存,作为循环结束条件
            
            for j in range(2,m2): # 用同样的原理判断n2是否为素数
                if n2%j==0 and j<n2:
                <!-- 4 --> #那么这里就应该照抄上面break
            else:
                print(x,'=',n1,'+',n2) #输出猜想验证
    
  6. 以下程序将输出右对齐九九乘法表,请把处缺少的代码补全。

    1×1=1
    2×1=2   2×2=4
    3×1=3   3×2=6   3×3=9
    4×1=4   4×2=8  4×3=12  4×4=16
    5×1=5  5×2=10  5×3=15  5×4=20  5×5=25
    6×1=6  6×2=12  6×3=18  6×4=24  6×5=30  6×6=36
    7×1=7  7×2=14  7×3=21  7×4=28  7×5=35  7×6=42  7×7=49
    8×1=8  8×2=16  8×3=24  8×4=32  8×5=40  8×6=48  8×7=56  8×8=64
    9×1=9  9×2=18  9×3=27  9×4=36  9×5=45  9×6=54  9×7=63  9×8=72  9×9=81
    
    for i in range(1,10):
       <!-- 1 -->
           s1=str(i)+'×'+str(j)+'='+str(i*j)
           print(<!-- 2 -->)  
       print()      
    
    答案:for j in range(1,i+1):'%8s'%(s1),end=''
    以下是添加了详细注释的代码以便理解:
    
    for i in range(1,10): # i从1遍历到9,作为九九乘法表的行
        <!-- 1 --> 
        # 九九乘法表还需要列,此处需要增加一个循环,根据九九乘法表的性质,这个循环最多只能遍历到i为止
            
           s1=str(i)+'×'+str(j)+'='+str(i*j) # 将每一格的计算结果拼接,暂存以供接下来的格式化输出
        
           print(<!-- 2 -->)  # 格式化输出,右对齐不需要多余的格式化字符,只需要指定宽度即可
            
        print() # 打印每一行的回车    
    
  7. 以下程序的功能是输出如下图形,请把处缺少的代码补全。

                  *
                 ***
                *****
               *******
              *********
             ***********
              *********
               *******
                *****
                 ***
                  *
    
    for i<!-- 1 -->:
            print(('*'*(2*i-1)).center(30))
    for i in range(6, 0, -1):
        print(<!-- 2 -->)
    
    答案:in  range(6)('*'*(2*i-1)).center(30)
    以下是添加了详细注释的代码以便理解:
    
    for i<!-- 1 -->: 
        # 由于上下两个金字塔相反,因此第一层循环必定与第二层相反
        #可知第二层循环从6到1,那么第一层循环应该是从1到5
        
        print(('*'*(2*i-1)).center(30)) 
        # 使用居中的格式控制来输出,避免了手打空格的窘境
        
    for i in range(6, 0, -1):
        
        print(<!-- 2 -->) 
        # 此处同理,应该和第一层的输出语句完全相同,两个循环的不同点只有i的递增/递减
    
  8. 下面的代码功能是判断回文串,请把处缺少的代码补全。

    s='雾锁山头山锁雾'
    low=0
    high=<!-- 1 -->
    while low<high:
        if <!-- 2 -->: #倒序和顺序不一样
            print(s,"不是回文") 
            <!-- 3 -->
        low += 1    
        <!-- 4 -->
    else:
        print(s,"是回文串")
    
    答案:len(s)-1、s[low]!=s[high]break、high-=1
    以下是添加了详细注释的代码以便理解:
    
    s='雾锁山头山锁雾' # 本代码采用双指针算法
    low=0 # low指针指向字符串最左端
    high=<!-- 1 --> # high指针指向字符串最右端
    
    while low<high:
    # 两个指针向中间靠拢,一边靠拢一边对比指向的字符是否相同,直到相遇为止
        
        if <!-- 2 -->: 
        # 如果两个指针指向的字符不同,说明不是回文字符串
            print(s,"不是回文") 
            <!-- 3 -->
        low += 1 #左指针向右移动    
        <!-- 4 --> #右指针向左移动   
    else: #此处是while的else,表示循环正常结束
        
        print(s,"是回文串") 
        # 如果循环正常结束说明检查没有问题,是回文串 
    
  9. 以下程序将输出如下内容,请把处缺少的代码补全。

    ==============================
                统计信息
    ------------------------------
    行数                         1
    单词数                       7
    字符数(包含空格)          33
    字符数(不包含空格)        27
    ------------------------------
    
    s='''I am a teacher! You are students!'''
    print('='*30)
    print('统计信息'.center(28))
    print(<!-- 1 -->)
    item_width=25
    line=s.count('\n')+1
    word=s.split() 
    char=list(s)     #包含空格、标点符号
    w_num=0
    for w in word:  
        w_num+=<!-- 2 -->
    print('%-*s %5d'%(item_width-3,'行数',line))
    print('%-*s %5d'%(<!-- 3 -->,'单词数',len(word)))
    print('%-*s %5d'%(item_width-10,'字符数(包含空格)',<!-- 4 -->))
    print('%-*s %5d'%(item_width-11,'字符数(不包含空格)',w_num))
    print('-'*30)
    
    答案:'-'*30len(w)、item_width-4len(char)
    以下是添加了详细注释的代码以便理解:
    
    s='''I am a teacher! You are students!'''
    # 要统计的源字符串
    
    print('='*30) # 输出表头
    
    print('统计信息'.center(28)) # 居中输出标题
    
    print(<!-- 1 -->) 
    # 根据题面,此处应该输出那一行----
    
    item_width=25 # 设置内部宽度
    
    line=s.count('\n')+1 # 通过计数换行符的个数来计算行数
    
    word=s.split() 
    # 通过split函数的默认行为:拆分空格和标点符号来创建单词列表
    
    char=list(s)
    #通过将字符串转为列表来计数字符数量
    
    w_num=0 
    # 根据下文可知该变量用于计数不包含空格的字符数量
    
    for w in word:  
    #遍历前面创建的单词列表,内容大概是['I','am','a']这样
        
        w_num+=<!-- 2 --> 
        #显然这边应该计数每个字符串元素的长度,使用len函数
        
    print('%-*s %5d'%(item_width-3,'行数',line)) 
    
    print('%-*s %5d'%(<!-- 3 -->,'单词数',len(word)))
    # 根据上下文的规律可以大概猜到这个item_width是用来将输出的长度控制对齐用的
    # 而对齐的方式就是这个 变量-(后面的描述词长度+1),那么此处应该填item_width - 4
    
    print('%-*s %5d'%(item_width-10,'字符数(包含空格)',<!-- 4 -->)) 
    # 根据上下文可知,该空应该填的是这个条目的数值,那么包含空格的字符数自然是len(char)
    
    print('%-*s %5d'%(item_width-11,'字符数(不包含空格)',w_num))
    
    print('-'*30) # 输出页脚
    
  10. 以下程序将输出以下图形,请把处缺少的代码补全。

    [1]
    [1, 1]
    [1, 2, 1]
    [1, 3, 3, 1]
    [1, 4, 6, 4, 1]
    [1, 5, 10, 10, 5, 1]
    [1, 6, 15, 20, 15, 6, 1]
    [1, 7, 21, 35, 35, 21, 7, 1]
    [1, 8, 28, 56, 70, 56, 28, 8, 1]
    [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
    
    def demo(t):
        print([1])
        <!-- 1 -->
        line = [1,1]
        for i in range(2,t):
            <!-- 2 -->
            for j in range(0,len(line)-1):
                r.append(<!-- 3 -->)
            line = [1]+r+[1]
            print(line)
    demo(<!-- 4 -->)
    
    答案:print([1, 1])、r=[]、line[j]+line[j+1]10
    以下是添加了详细注释的代码以便理解:
    # 本题考查打印杨辉三角的算法
    # 杨辉三角的性质是:每一行的每一个元素,
    # 都等于上一行对应位置的元素+上一行对应位置元素左侧的元素,规律可以看样例输出来理解
    
    def demo(t): 
        print([1]) # 杨辉三角的第一行和第二行是需要特判的,一个是1,一个是1 1
        <!-- 1 --> # 因此空缺处应该打印[1, 1]
        
        line = [1,1] # 第二行保留用于生成接下来的所有行
        
        for i in range(2,t): 
        # 接下来生成t行杨辉三角,由于预先特判了2行,因此循环从2开始
            
            <!-- 2 -->
            # 根据下文可知,有一个r没被声明
            # 而根据r.append()可以看出r是列表
            
            for j in range(0,len(line)-1):
            # 接下来生成每行的中间元素,即去掉头尾的1后中间的那些
                
                r.append(<!-- 3 -->)
                # 根据杨辉三角的性质,
                # 元素应该等于上一行对应位置的元素+上一行对应位置元素左侧的元素
                # 因此r的第j个元素应该等于line的第j个元素(因为line包括最左侧的1)+line的第j+1个元素
                
            line = [1]+r+[1] 
            # 将结果放入line中,生成下一行
            # 杨辉三角的左右都是1,因此还需要在左右各加上一个[1]
            
            print(line) # 打印当前行
            
    demo(<!-- 4 -->) 
    # 由于样例中生成了10行杨辉三角,可知此时函数调用的t应该是10
    

你可能感兴趣的:(python)