数据结构与算法Python语言实现第一章课后习题(完整篇)

数据结构与算法Python语言实现第一章课后习题

R-1.1 编写一个Python函数is_multiple(m,n),用来接收两个整数值n和m,如果n是m的倍数,即存在整数i使得n=mi,那么函数返回True,否则返回false。

def is_multiple(n,m):
     return(n%m==0)
>is_multiple(16,4)
>True
>is_multiple(16,3)
>False

R-1.2 编写一个python函数is_even(k),用来接收一个整数K,如果K是偶数返回True,否则返回False。但是在函数中不但能使用乘法、除法或者取余操作。

def is_even(k):
    return(k&1==0)  #按位与  当k与1全部为1时才取1.
 >is_even(-10)
 >True
 >is_even(5)
 >False

R-1.3 编写一个Python函数minmax(data),用来在数的序列中找出最小数和最大数,并以一个长度为2的元组的形式返回,注意:不能通过内置函数min和max来实现。

#解法一:
def minmax(data):
    maxx=0
    minn=0
    for j in range(0,len(data)):
        if data[j]>data[maxx]:
            maxx=j
        if data[j]<data[minn]:
            minn=j 
    return (data[maxx],data[minn])  
    
 >minmax([2,4,5,6,8,1])
 >(8, 1)    
#解法二:
def minmax(data):
    max=min=data[0]
    for val in data:
        if val<min:
            min=val
        if val>max:
            max=val
    return(max,min)
   
 > minmax([2,4,5,6,82,1])
 > (82, 1)

R-1.4编写一个Python函数,用来接收正整数 n,返回 1 ~ n 的平方和。

#解法一:
def ji(n):
    return (sum(pow(i,2) for i in range(n+1)))
>ji(5)
>55
#解法二:
def sun_square(n):
    total=0
    for k in range(1,n+1):
        total+=k*k
     return (total)
>sun_square(5)
>55

R-1.5 基于Python的解析语法和内置函数 sum,写一个单独的命令来计算练习R-1.4中的和。

def sun_square(n):
    return(sum(k*k for k in range(1,n+1)))
>sun_square(5)
>55

R-1.6 编写一个Python函数,用来接收正整数n,并返回 1 ~ n 中所有的奇数的平方和。

def sum_ord_square(n):
    total=0
    for k in range(1,n+1,2):
        total+=k*k
    return(total)
    
>sum_ord_square(10)
>165

R-1.7 基于Python的解析语法和内置函数 sum,写一个单独的命令来计算练习R-1.6中的和。

def sum_or_square(n):
    return(sum(k*k for k in range(1,n+1,2)))
>sum_or_square(10)
>165

R-1.8 Python 允许负整数作为序列的索引值,如一个长度为 n 的字符串 s,当索引值 -n <= k < 0 时,所指的元素为 s[k],那么求一个正整数索引值 j >= 0,使得 s[j] 指向的也是相同的元素。

n=9
k=-3
data=[1,2,3,3,4,5,6,8,9]
print(data[k])
j=n+k
print(data[j])
>6
>6

R-1.9 要生成一个值为 50, 60, 70, 80 的排列,求 range构造函数的参数.

for i in range(50,82,10):
    print(i,end=' ')          #end=' '表示每个输出用空格来隔开
>50 60 70 80 

R-1.10 要生成一个值为 8, 6, 4, 2, 0, -2, -4, -6, -8 的排列,求 range 构造函数中的参数。

for i in range(8,-10,-2):
    print(i,end=' ') 
>8 6 4 2 0 -2 -4 -6 -8 

R-1.11演示怎样使用 Python 列表解析语法来产生列表 [1, 2, 4, 8, 16, 32, 64, 128, 256].

list(2**k for k in range(9))
>[1, 2, 4, 8, 16, 32, 64, 128, 256]

list(map((lambda x: 2 ** x), range(9)))
>[1, 2, 4, 8, 16, 32, 64, 128, 256]

R-1.12 Python 的 random 模块包括一个函数 choice(data),可以从一个非空序列返回一个随机元素。Random模块还包含一个更基本的 randrange 函数,参数化类似于内置的 range 函数,可以在给定范围内返回一个随机数。只使用 randrange 函数,实现自己的 choice 函数。

def mychoice(data):
    import random
    return data[random.randrange(len(data))]
    
>data=[1,2,3,8]
>mychoice(data)
>2

R-1.13 编写一个函数的伪代码描述,该函数用来逆置 n 个整数的列表,使这些以相反的顺序输出,并将该方法与可以实现相同功能的 Python 函数进行比较。

def myReverse(data):
    return data[::-1]
 
>data=[1,4,5,7,3,0]
>myReverse(data)
>[0, 3, 7, 5, 4, 1]

lista = [1, 2, 3, 4]
lista.reverse()
print(lista)
>[4, 3, 2, 1]

l=[22,45,26,34,56,78]
for i in reversed(l):
    print(i,end=' ')
>78 56 34 26 45 22

R-1.14 编写一个 Python 函数,用来接收一个整数序列,并判断该序列中是否存在一对乘积是奇数的互不相同的数

#解法一:
def productIsOdd(lst):
    lst=[i for i in lst if i%2>0]
    if len(set(lst))>=2:
        return True
    else:
        return False
>lst=[2,3,3,4,5]
>productIsOdd(lst)
>True
#解法二:
def hasOddMut1(data):
    temp = []
    for item in data:
        if item % 2 != 0 and item not in temp:
            temp.append(item)
    if len(temp) >= 2:
        return True
    else:
        return False
#解法三
def hasOddMut2(data):
    temp = set()            #set确保列表的元素各不相同
    for item in data:
        if item % 2 != 0:
            temp.add(item)
    return (len(temp) >= 2)
>data = [1, 2, 4, 6, 8, 3]
>hasOddMut2(data)
>True

R-1.15 编写一个 Python 函数,用来接收一个数字序列,并判断是否所有数字都互不相同

def notsame(lis):
    for i in range(len(lis)):
        for j in range(i):
            if lis[j]==lis[i]:
                return False
    return True
>lis=[1,2,3,45,6]
>notsame(lis)
>True
#解法二:
def isDiff1(data):
    temp = set()
    for item in data:
        if item not in temp:
            temp.add(item)
        else:
            return False
    return True
#解法三:高效利用set
def isDiff2(data):
    return (len(data) == len(set(data)))

R-1.17 1.5.1节 scale 函数的实现如下。它能正常工作吗?请给出原因。

def  scale(data, factor):
    for val in data:
        val = val * factor

it can’t work.val只是对data列表中数据的引用,是一个变量,而不是列表元素对象本身。需要在对象上改变,需要采用索引的方法

R-1.18 演示如何使用 Python 列表解析语法来产生列表 [0, 2, 6, 12, 20, 30, 42, 56, 72, 90]。

lis=[i*(i+1) for i in range(10)]
print(list)
>[0, 2, 6, 12, 20, 30, 42, 56, 72, 90]

R-1.19 演示如何使用 Python 列表解析语法在不输入所有 26 个英文字母的情况下产生列表 [‘a’, ‘b’, ‘c’,…, ‘z’]。

lis=[chr(ord('a')+i) for i in range(26)]
print(lis,end=' ')
>['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'] 

R-1.20 Python 的 random 模块包括一个函数 shuffle(data),它可以接受一个元素的列表和一个随机的重新排列元素,以使每个可能的序列发生概率相等。 random 模块还包括一个更基本的函数 randint(a, b),它可以返回一个 a 到 b (包括两个端点)的随机整数。只使用 randint 函数,实现自己的 shuffle 函数。

def myshuffle(lis):
    import random
    lislen=len(lis)    #lis的长度
    shuffle=[]        #定义一个空列表
    lis2=list(range(len(lis)))  #用lis的长度来range一个列表,复制给lis2
    while lis2:               
        i=random.randint(0,lislen-1)     #i 取值为0-(lis-1)长度的随机值
        if i in lis2:                                  
            shuffle.append(lis[i])         #从shuffle列表中添加 lis[i]元素
            lis2.remove(i)                   #将i 元素从lis2中去除
    lis[:]=shuffle[:]                          #直到lis列表等于shuffle列表相等时 跳出循环

R-1.21 编写一个Python程序,反复从标准输入读取一行直到抛出 EOFError 异常,然后以相反的顺序输出这些行(用户可以通过键按 Ctrl + D 结束输入)。

def func():
    ls=[]
    while True:
        try:
            line=input()
            l=list(map(int,line.split()))
            ls=l[::-1]
            print(ls)
        except ValueError:
            print("错误")
            
func()
>1 2 3
>[3, 2, 1]
>sad d a
>错误

R-1.22 编写一个Python程序,用来接收长度为 n 的两个整型数组 a 和 b 并返回数组 a 和 b 的点积。也就是返回一个长度为 n 的数组 c,即 c[i] = a[i] ⋅⋅ \cdot⋅ b[i], for i = 0, …, n-1.

#解法一:
def ab(a,b):
    c=[a[i]*b[i] for i in range(0,len(a))]
    return c 
>a=[1,2,3]
>b=[2,3,4]
>ab(a,b)
>[2, 6, 12]
#解法二:
def ab2(a,b):
    import numpy as np
    return np.array(a)*np.array(b)
>a=[1,2,3]
>b=[2,3,4]
>ab2(a,b)
>array([ 2,  6, 12])

R-1.23 给出一个 Python 代码片段的例子,编写一个索引可能越界的元素列表。如果索引越界,程序应该捕获异常结果并打印以下错误消息:“Don’t try buffer overflow attacks in Python!”

def function(data,i):
    try:
        return data[i]
    except IndexError:
        print("Don't try buffer overflow attacks in Python!")
>data=[2,35,4]
>function(data,2)
>4
>function(data,6)
>Don't try buffer overflow attacks in Python!

R-1.24 编写一个 Python 函数,计算所给字符串中元音字母的个数

def numberOFvowels(s):
    vowels=['a','e','i','o','u','A','E','I','O','U']
    compte=[]
    for i in s:
        if i in vowels:
            compte.append(i)
    return len(compte)
>s=['s','a','f','e','u']
>numberOFvowels(s)
>3
def num_vowels(tex):   
    total=0
    for i in tex.lower():
        if i in 'aeiou':
            total+=1
    return tota
>tex='AEiyrho'
>num_vowels(tex)
>4

R-1.25 编写一个 Python函数,接收一个表示一个句子的字符串 s,然后返回该字符串的删除了所有标点符号的副本。例如, 给定字符串 “Let’s try, Mike.”,这个函数将返回 “Lets try Mike”。

def removePunctuation(s):
    import string
    punctuation=string.punctuation  #punctuation调用string中的字符串,赋值给punctuation
    s2=''
    for i in s:
        if i not in punctuation:
            s2+=i
    return s2
>s='djas*dsa$ldas w #kfja'
>removePunctuation(s)
>'djasdsaldas w kfja'

R-1.26 编写一个程序,需要从控制台输入 3 个整数 a、b、c,并确定它们是否可以在一个正确的算术公式(在给定的顺序)下成立,如“a + b = c” “a = b - c” 或 “a * b = c”。

def function():
    a=int(input('a:'))
    b=int(input('b:'))
    c=int(input('c:'))
    if (a+b==c) or (a==b-c) or (a*b==c):
        return True
    else:
        return False
>function()
>a:1
>b:2
>c:5
>False

R-1.27 在 1.8 节中,我们对于计算所给整数的因子时提供了 3 种不同的生成器的实现方法。 1.8 节末尾处的第三种方法是最有效的,但我们注意到,它没有按递增顺序来产生因子。修改生成器,使得其按递增顺序来产生因子,同时保持其性能优势。

def factors(n):
    k = 1
    temp = []
    while k * k < n:
        if n % k == 0:
            yield k
            temp.append(n // k)
        k += 1
    if k * k == n:
        yield k
    for item in temp[::-1]:
        yield item

>list(factors(100))
>[1, 2, 4, 5, 10, 20, 25, 50, 100]

R-1.28 在 n 维空间定义一个向量 v=(v1,v2,…,vn) v=(v1,v2,…,vn) 的 p 范数, 如下所示:
||v||=(v1P+V2P+…VnP)(1/p)
对于 p = 2 的特殊情况,这就成了传统的欧几里得范数,表示向量的长度。例如,一个二维向量坐标为 (4,3) 的欧几里得范数为(42+32)(1/2)=(16+9)(1/2)=25**(1/2).编写 norm 函数,即 norm(v, p),返回向量 v 的 p 范数的值, norm(v),返回向量 v 的欧几里得范数。你可以假定 v 是一个数字列表。

def norm(v,p=2):
    sum=0
    for i in v:
        sum=sum+pow(i,p)
    return pow(sum,1.0/p)
>norm((4,3))
>5.0

R-1.29 编写一个 Python 程序,输出由字母 ‘c’,‘a’,‘t’,‘d’,‘o’,‘g’ 组成的所有可能的字符串(每个字母只使用1次)

import itertools    #itertools无限迭代器
x=itertools.permutations(['a','c','t','d','o','g'],6) #permutations全排列
print(list(map(''.join,x))) 
def allStr():
    s=['c','a','t','d','o','g']
    for i in s:
        #print(i)
        ss=s.copy()
        ss.remove(i)
        for j in ss:
            #print(i+j)
            sss=ss.copy()
            sss.remove(j)
            for k in sss:
                #print(i+j+k)
                ssss=sss.copy()
                ssss.remove(k)
                for m in ssss:
                    
                    #print(i+j+k+m)
                    sssss=ssss.copy()
                    sssss.remove(m)
                    for n in sssss:
                        #print(i+j+k+m+n)
                        ssssss=sssss.copy()
                        ssssss.remove(n)
                        for p in ssssss:
                            print(i+j+k+m+n+p)   

R-1.30 编写一个 Python 程序,输入一个大于 2 的正整数,求将该数反复被 2 整除直到商小于 2 为止的次数

def isdivid():
    a=int(input('a:'))
    num=0
    while a>=2:
        a=int(a/2)
        num+=1
    return num
>isdivid()
>a:33
>5

R-1.31 编写一个可以“找零钱”的 Python 程序。程序应该将两个数字作为输入,一个是需要支付的钱数,另一个是你给的钱数。当你需要支付的和所给的钱数不同时,它应该返回所找的纸币和硬币的数量。纸币和硬币的值可以基于之前或现在政府的货币体系。试设计程序,以便返回尽可能少的纸币和硬币。

def cahngenote():
    youpay=int(input("你所付的钱:\n"))
    shouldpay=int(input("应该付的钱:\n"))
    if youpay>shouldpay:
        givechange=int(youpay-shouldpay)
        if givechange<5:
            purse=givechange
            print("找零:", purse)
        if givechange>5:
            purse1=givechange-5
            purse2=purse1
            print("找零:","5","和",purse2) 
def makeChange(changed,given):
    coin=[100,50,20,10,5,1,0.5,0.1]
    change=given-changed
    if change==0:
        return 
    i=0
    ok=True
    while ok:
        if coin[i]<=change:
            print("面值"+str(coin[i])+"张数"+str(change//coin[i]))
            ok=False
            makeChange(0,change%coin[i])
        i+=1
> makeChange(33,100)
> 面值50张数1
面值10张数1
面值5张数1
面值1张数2
def function():
    coins={'0.5':0,'1':0,'5':0, '10':0, '20':0, '50':0, '100':0}
    temp=input("输入应付的钱和总的钱:\n").split(" ")
    pay,total=int(temp[0]),int(temp[1])
    rest=total-pay
    
    coins[100]=int(rest/100)
    rest = int(rest % 100)
    coins[50] = int(rest / 50)
    rest = int(rest % 50)
    coins[20] = int(rest / 20)
    rest = int(rest % 20)
    coins[10] = int(rest / 10)
    rest = int(rest % 10)
    coins[5] = int(rest / 5)
    rest = int(rest % 5)
    coins[1] = int(rest / 1)
    rest = int(rest % 1)
    coins[0.5] = int(rest / 0.5)
    rest = int(rest % 0.5)
    
    return coins.values()
>function()
>输入应付的钱和总的钱:32 56
>dict_values([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 4, 0])

R-1.32 编写一个 Python 程序来模拟一个简单的计算器,使用控制台作为输入和输出的专用设备。也就是说,计算器的每一次输入做一个单独的行,它可以输入一个数字(如1034或12.34)或操作符(如 + 或 = )。每一次输入后,应该输出计算器显示的结果并将其输出到 Python 控制台。

def function32():
    temp = input("Please input Number1 Operation Number2: \n").split(" ")
    num1 = int(temp[0])
    num2 = int(temp[2])
    oper = str(temp[1])
    if oper == '+':
        result = num1 + num2
    elif oper == '-':
        result = num1 - num2
    elif oper == '*':
        result = num1 * num2
    elif oper == '/':
        result = num1 / num2
    else:
        raise EOFError("Error Input!")
    return result
>function32()
>Please input Number1 Operation Number2: 8 * 8
>64

R-1.34 一种惩罚学生的常见方法是让他们将一个句子重复写很多次。编写独立的 Python 程序,将以下句子 “I will never spam my friends again.” 写 100 次。程序应该对句子进行计数,另外,应该有 8 次不同的随机输入错误。

from random import choices,choice
from time import sleep
def get_space_index(sample):
    sample=list(sample)  #sample转换成list列表
    space_index_list=[]  #定义一个空列表
    while ' ' in sample:    #当sample中有空格时
        index=sample.index(' ')  #将sample空格的索引赋值给index
        space_index_list.append(index+len(space_index_list))  #在space_index_list 列表中添加索引和长度
        sample.pop(index)
    return space_index_list
def punish_write():
    sample=list(" I will never spam my friends again.")
    cnt=0
    wrong_cnt=8
    wrong_index_list=choices(list(range(100)),k=8)#拼写错误的索引组成的列表
    print(wrong_index_list) 
    space_index_list=get_space_index(sample)  #调用上述定义的函数,创造sample中含有的空格的索引列表
    wrong_times=0 #错误0次
    while cnt<100:
        if cnt in wrong_index_list:#如果当前的索引在错误列表索引中
            wrong_times+=1
            while True:
                wrong=choice(range(len(sample)))#选择在sample列表的任意一部分出错的索引,并将之赋值给wrong
                if wrong not in space_index_list:#如果出现错误的地方不在空格列表中
                    sample[wrong]=choice([chr(i) for i in range(65,65+26)]+[chr(i) for i in range(97,97+26)]+[',','.'])#错误出现在字母拼写中
                    break
            for i in sample:
                print(i,end='')
                sleep(0.05)
            print(' |{:3d}| \twrong {}'.format(cnt+1,wrong_times),end='\n')
            sleep(0.1)
        else:
            for i in sample:
                print(i,end='')
                sleep(0.03)
            print('|{:3d}|'.format(cnt+1),end='\n')
            sleep(0.1)
        cnt+=1
        sample=list(" I will never spam my friends again.")

R-1.35 生日悖论是说,当房间中人数 n 超过 23 时,那么该房间里有两个人生日相同的可能性是一半以上。这其实不是一个悖论,但许多人觉得不可思议。设计一个 Python 程序,可以通过一系列随机生成的生日的实验来测试这个悖论,例如可以 n = 5, 10, 15, 20, …, 100 测试这个悖论。

def function(num):
    import math
    from decimal import Decimal
    prop=1-Decimal((math.factorial(365)))/Decimal(math.pow(365,num)*math.factorial(364-num))
    return prop
def functions(num):
    import math
    prop=1-math.pow((364/365),(num*(num-1)/2))
    return prop
>functions(32)
>0.7435365267749252

R-1.36 编写一个 Python程序,输入一个由空格分隔的单词列表,并输出列表中的每个单词出现的次数。在这一点上,你不需要担心效率,因为这个问题会在本书后面的部分予以解决。

def function1():
    import string
    temp=input("输出一行字符:\n").strip(string.punctuation).split(" ")
    keys=list(set(temp))
    result=dict(zip(keys,[0]*len(keys)))
    for item in temp:
        result[item]+=1
    return result
>function1()
>输出一行字符: "w jj w "
>{'w': 2, '': 1, 'jj': 1}
  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值