这个博客权当我自己的学习记录,所以参考一些网上的代码 数据结构与算法Python语言实现第一章课后习题(完整篇)_王胖子总叫我减肥的博客-CSDN博客 这位大牛的代码让我获益良多,感谢感谢。
1.1
def is_multiple(n,m):
if n%m==0:
return True
else:
return False
print(is_multiple(12,5))
1.2
def is_even(num):
num=str(num)
unit=num[-1]
if unit in ['0','2','4','6','8']:
return True
else:
return False
print(is_even(47))
1.3自己的思路
def maxmin(data):
length=len(data) #6
max_num=0
for i in range(length-1): #5,只能取到4,如果是(1,length)会报错,少取一个数,
if data[i]>data[i+1]: #但下面有i+1,所以并不会漏掉最后一个
data[i],data[i+1]=data[i+1],data[i]
max_num=data[i+1]#取最后一个,因为第一个和第二个比,大的话换位置,大的在后面
print(data[i+1]) # 6
min_num = 0
for j in range(length - 1):
if data[j] < data[j + 1]:
data[j],data[j+1]=data[j+1],data[j]
print(data[j+1]) #还是最后一个,前两个比,如果第一个小,换位置,小的还是在后面
min_num=data[j+1] #1
# print的值和return的值不一样,i最后的存留值是4,加1为5,此时data的顺序已变了,
# 最后一个是最小的,而前面赋值的,max,min不会变化
# print(data.index(data[i+1]),data[i+1],data.index(data[j+1]),data[j+1])
return max_num,min_num
print(maxmin(['3', '4', '2', '1', '6', '5']))
方法二:用选择排序做
# 用选择排序做
def maxmin(data):
length=len(data)
for i in range(length-1):
for j in range(i+1,length):
if data[i]>data[j]:
data[i],data[j]=data[j],data[i]
return '{}为最大的数{}为最小的数'.format(data[5],data[0])
print(maxmin(['3', '2', '4', '5', '6', '1']))
方法三:用冒泡排序做
def maxmin(data):
length=len(data)
for i in range(1,length):
for j in range(length-i):
if data[j]>data[j+1]:
data[j],data[j+1]=data[j+1],data[j]
return '最小的数为%s最大的数为%s'%(data[0],data[5])
print(maxmin(['3', '2', '4', '5', '6', '1']))
1.4
def sum_squares():
inp=int(input('请输入整数:\n'))
temp=0
for i in range(1,inp+1):
temp+=i**2
return temp
print(sum_squares())
1.5
a=sum([i*i for i in range(11)])
print(a)
##########1.6 # def a_add(a): # c=0 # for i in range(a): # if i%2!=0: # b=i**2 # c+=b # return c # print(a_add(int(input('数字:')))) #1.7 # n=int(input("数字:")) # even_square_sum=sum([i*i for i in range(n) if i%2!=0]) # print(even_square_sum) # 1.8
k=-5
a=['1', '2', '3', '4', '5', '6', '7']
length=len(a)
print(a[k])
j=k+length
print(a[j])
# 1.9
for i in range(50,90,10):
print(i,end="")
# 1.10 # for i in range(8,-9,-2): # print(i)
1.11
list1=[2**i for i in range(9)]
1.12
data=['1', '2', '3', '4', '5', '6', '7'] def Mychoice(data): import random return data[random.randrange(len(data))] Mychoice(data)
1.13
data=['1', '2', '3', '4', '5', '6', '7'] print(data[::-1]) for i in range(len(data)-1,-1,-1): print(data[i],end=' ') data.sort(reverse=True) print('\n',data) data.reverse() print(data) for i in reversed(data): print(i,end=' ')
1.14
# 解法一,直接求出所有乘积是奇数,且两者互不相同的数
temp=[i for i in range(10)] def ji_even(data): temp_list=[] for i in range(1,len(data),2): for j in range(i+2,len(data),2): # 代码优化了一下,下面这一步可以去掉 # if data[i]*data[j]%2!=0 and data[i]!=data[j]: temp_list.append([data[i],data[j]]) return temp_list result=ji_even(temp) print(result)
解法二
# 二因为只要是奇数乘奇数,结果必然是奇数,所以只需要确定有两个以上奇数,且互不重复
temp=[i for i in range(10)] def ji_even(data): temp_list=[i for i in data if i%2!=0] if len(temp_list)>=2: return True else: return False result=ji_even(temp) print(result)
1.15
temp=[i for i in range(10)] def different_numbers(data): temp_set=set(data) if len(temp_set)==len(data): return True else: return False result=different_numbers(temp) print(result)
#解法二,for循环竟然还可以这样用,我之前还以为这样的话,这个比较的数字要是跟自己本身比起来不就是一样的,然后程序执行出错误的结果,其实不是的,因为stop只能取到之前的一位,所以j,i永远也不会同时取到同一个值。
def notsame(temp): for i in range(len(temp)): for j in range(i): if temp[i]==temp[j]: return False return True result=notsame(temp) print(result)
1.16
temp=[i for i in range(10)] def scale(data,factor): for i in range(len(data)): print(id(data[i]),'--',data[i]) data[i]*=factor print(id(data[i]),data[i]) return data result=scale(temp,2)
1846563584 -- 0
1846563584 0
1846563616 -- 1
1846563648 2
1846563648 -- 2
1846563712 4
1846563680 -- 3
1846563776 6
1846563712 -- 4
1846563840 8
1846563744 -- 5
1846563904 10
1846563776 -- 6
1846563968 12
1846563808 -- 7
1846564032 14
1846563840 -- 8
1846564096 16
1846563872 -- 9
1846564160 18
由以上数据可以看出,两个print打印出的列表中同下标元素的id地址不一样,在数字类型不可变情况下,只能是虚拟机用计算出的结果,替换掉原下标上的元素,列表中的元素是可变的。
但仔细观察又可以看出,以上两个print打印出的数字是有不少相同的,它们的id地址也是一样的,说明在虚拟机内部,每个数字(字符串也一样)固定分配一个地址,列表中的数字其实只代表了一个地址,同一个数字可以出现在多个位置,因为每个位置上的数字只不过是个地址,最终指向一个唯一的数字。
最后又试了一下深拷贝,id地址依然不变,可见我的推论是正确的.
1.17
# def scale(data,factor): # for var in data: # # a=data.index(var) # # print(a,data) # # data.insert(a,var+factor)#这条语句使for无限循环,每循环一次,往列表中插入一个数字,列表无穷大了 # var+=factor#如果列表中全是数字,则可以运行,如果是字符串则不可以运行 # # # # print(var,id(var))这里我打印出了var的地址,与1.16题目中相同数字的地址完全一样,进一步印证了我的推测,同一个数字,一个机器中只有一个,其他都是引用,但不同机器同一个数字存储的位置可能并不相同。 # # return var # print(scale([1,2,3,4,5,6,7,8,9,],5))
# 1.18 a=[i*(i+1) for i in range(10)]
1.19
a=[chr(i) for i in range(97,123)]
1.20
import random a=[';', 'k', 'a', 'd', 's', 'f', 'k', ';', 'g', 'h'] random.shuffle(a) # print(a)#随机序列 rand=random.randint(1,100)#随机一个数字 def myshuffle(data): temp=[] length=len(data) for i in range(length): temp_str=data[random.randint(0,length-1)] temp.append(temp_str) data.remove(temp_str) # data.pop(data.index(temp_str)) length-=1 return temp print(myshuffle(a))
1.21
def func(): ls=[] while True: try: line=input("输入:") l=list(map(int,line.split())) #这行代码错了,split是以一个元素分割字符串, # 默认是空格,但是输入字符中没有空格则不能成功,如果设置其他参数,如没有输入此参 数,还是不能成功 # 可见,split用在这里是不合适的,list()方法则可以 l=list(map(int,list(line))) ls=l[::-1] li2s=map(lambda x:x**2,ls) print(ls) print(list(li2s)) except ValueError: print("错误") func() 下面是map函数的一些用法 def f(a): return a**a b=[1,3,2,3] a=list(map(f,b)) print(a) li2s=map(lambda x:x**2,ls) l=list(map(int,list(line))) print(list(li2s))
1.22
def dot_pro(a,b): list1=[] for i in range(len(b)): list1.append(a[i]*b[i]) return list1 ss=[1,2,3,4,5] dd=[1,2,3,4,5] print(dot_pro(ss,dd))
import numpy as np def dot_pro(a,b): return np.array(a)*np.array(b) print(dot_pro(ss,dd))
s=4 e=5 ff=lambda x,y:x+y print(ff(s,e)) ss=[1,2,3,4,5] dd=[1,2,3,4,5] aa=list(map(lambda x,y:x*y,ss,dd)) print(aa)
1.23
a='g;agj;reghoeg' b=list(a) try: for i in range(100): print(b[i]+b[i]) except IndexError: print("Don't try buffer overflow attacks in python") raise #用于引发一个异常,如果不注释,则也会抛出异常IndexError finally: print('谢谢配合')
1.24
def judge_isletter(): inp = input('请不要掺杂其他字符,只输入字母:') if inp.isalpha(): return inp else: return judge_isletter() vowel=['A', 'a', 'E', 'e', 'I', 'i', 'O', 'o', 'U', 'u'] def judge_vow(data): flag = 0 vowel_list=[] for i in data: if i in vowel: vowel_list.append(i) flag+=1 print(i,'是元音字母') else: print(i,"不是元音字母") return '总共%s个元音字母'%flag,vowel_list while True: temp=judge_isletter() a=judge_vow(temp) print(a)
1.25
data="Don't,try.buffer?overflow-attacks-in python" punctation=[',','.',':','!','-','?',';',] def solution(d): new_d=d.replace("'", '') for i in new_d: if i in punctation: result=new_d.replace(i,' ')#这条语句只执行字符串中最后一个标点替换的结果, # 因为replace方法不改变原字符串,标点每替换一次,给result赋值一次, # 之前的标点替换成功之后,最后一次将之前的result覆盖了。改成下面的执行语句便没有问题了 new_d=new_d.replace(i,' ') return new_d print(solution(data))
1.26
def calculate(): try: inp=int(input('输入第一个数字:')) inp1=int(input('输入第二个数字:')) inp2=int(input('输入两者相乘和:')) if inp*inp1==inp2: return '成立' else: return '不成立' except ValueError: print('请输入数字,不要输入其他字符,谢谢配合') return calculate() while True: print(calculate())
1.27
# inp = int(input('请输入一个数字:')) # def seek_factors(data): # k=1 # while k*k<inp: # if inp%k==0: # yield k # yield inp//k # k+=1 # else: #如果不加k+=1这一步,直接pass或者continue,函 # # 数跳过本次循环,但k也永远是一个定值,就会无限循环 # k+=1 # pass # if k*k==inp: # yield k # # # f=seek_factors(inp) # while True: # try: # print(next(f)) # while循环依然继续,但已迭代完成,就会引发stopiteration, # #next后面可以有个默认值,迭代完成后会返回它,就不会引发异常 # # 但加了默认值,因为永远有值了,while又无限循环(我故意将代码写得复杂一些,将可能涉及到的问题,抛出的异常等搞清楚,将自己想的一些思路尽量写进去,尽量涉及广的代码语句,并修改它的bug,有时会造成代码逻辑重复,但这对练习一门语言来说是有利的) # except StopIteration: # break
# 下面是以增序的方式,且性能优势不变,返回函数的值。
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 f=factors(100) # print(list(f)) # 下面这个循环和上面的print可以执行同样的功能(但会报StopIteration),在上面的代码中,yiled每次返回一个因子,而最后的for # 循环将n//k值的存储列表倒序遍历,将每一个因子返回,此时整个生成器返回的是一个个因子,且因为程序先后顺序, # 值自然是从小到大,print(f)打印的是一个生成器地址,加上一个list方法,则可将所有值封装成一个列表打印。 while True: print(next(f))
1.28
# 向量v的2范数是指欧里几得范数,即行的所有因子平方再求和再开平方,向量v的p范数便显而易见 def vector_operate(n,p=2):#默认参数,如果只传入一个n值,p就用此参数 temp=0 for i in n: temp+=i**p return pow(temp,1/2) result=vector_operate([3,4],3) print(result)
1.29字符串全位置转换
(s=''): # if len(s) <= 1: # # s+=s # return [s] # str_list = [] # for i in range(len(s)): # for j in str_sort(s[0:i] + s[i + 1:]): # str_list.append(s[i] + j) # return str_list # str_list = str_sort('abcde') # print(len(str_list), str_list)
1.30
inp=int(input("请输入一个大于2的整数:")) def exact_division(data): count=0 while True: data//=2 count+=1 if data<2: break return count print(exact_division(inp))
1.31
def just_change(): try: give=float(input("请输入您所给的钱:\n")) changed=float(input('请输入您消费的钱:\n')) if give<changed: print('您输入的钱不够支付本次消费') return just_change() else: return compute_change(give,changed) except: print('请输入数字,不要输入其他字符\n') return just_change() def compute_change(give,changed): coin = [100, 50, 20, 10, 5, 1, 0.5, 0.1] change = round(give - changed,1) if change==0: return i = 0 flag=True while flag: if coin[i] <= change: print("支付", coin[i], '元',change // coin[i], '张') flag=False # print(change, 'klj', coin[i],) #0.9//0.5 #1 change=change%coin[i] #0.9%0.5 #0.4 # print(change,round(change,1)) compute_change(round(change,1),0) i += 1 # print(compute_change(10,1.111)) print(just_change())
1.32
def compute_machine(): inp=float(input('请输入数字:\n')) inp2=float(input("请输入第二个数字:\n")) inp3=input('请输入操作符:\n') if inp3=='+': result=inp+inp2 elif inp3=='-': result=inp-inp2 elif inp3=='*': result=inp*inp2 elif inp3=='/': result=inp /inp2 return result while True: print(compute_machine())
1.33
import random # 随机产生一个字母,随机产生8个1至100的数(行), # 随机产生一个0至33的数(字母坐标),在那随机的一行将那个随机下标字母删掉,将随机字母插入. ran_lin = random.sample(range(1, 100), 8) sentence='I will never spam my friends again' def repeat_sentencen(): count = 0 while count<=100: #以此来控制总打印次数 ran_str = random.sample('zyxwvutsrqponmlkjihgfedcba', 1)[0] ran_ind = random.randrange(0, 33) #上面两行是产生随机字母和随机下标,以便执行插入删除指令 #之所以放在这里,是因为当程序进入while循环之中,第一次随机错误产生执行完以后, # 执行了两个del语句,如果不放在这里,这两个语句就执行不到,第二次获取数值时会抛出 #异常 if count in ran_lin: #如果count走到了ran_lin的行数 temp=sentence[:ran_ind] add_sente=temp+ran_str+sentence[ran_ind+1:] del ran_ind del ran_str print(count,add_sente) count += 1 elif count not in ran_lin: print(count,sentence) count += 1 print(repeat_sentencen())
1.34
#23个人,他们中有两个人生日相同,这个比率是%50左右。 #我们试上一万次,看看结果是不是这样,先产生一个10000次的变量,然后利用random.randint # (1,365)产生一个随机数字,假设它是一个人的生日,将这个数字放入列表之中, # 一次性23个生日全部放入,如果有相同的,count加1,看看10000次中有多少次相同的, # count/10000*100的值就是相同的比率 import random times=10000 persons=23 def birthday_rate(): count = 0 for i in range(times): birthday_lis = [] for j in range(23): birthday_lis.append(random.randint(1,365)) length=len(birthday_lis) length1=len(set(birthday_lis)) if length!=length1: count+=1 print(count,times) return '{0}个人生是相同的比率是{1}'.format(persons,count/times*100) print(birthday_rate()) 嗯,结果是%50左右,我们验证了这个悖论。
让我们改一下代码,看看n个人生日相同的比率是多少
好家伙,这代码挺吃计算机性能的,都快跑不动了,
import random
times=10000
def birthday_rate(person_times):
count = 0
for i in range(times):
birthday_lis = []
for j in range(person_times):
birthday_lis.append(random.randint(1,365))
length=len(birthday_lis)
length1=len(set(birthday_lis))
if length!=length1:
count+=1
return '{0}个人生日相同的比率是{1}'.format(person_times,count/times*100)
for i in range(2,100):
print(birthday_rate(i))
#
2个人生日相同的比率是0.19
3个人生日相同的比率是0.91
4个人生日相同的比率是1.51
5个人生日相同的比率是2.52
6个人生日相同的比率是4.24
7个人生日相同的比率是5.57
8个人生日相同的比率是7.580000000000001
9个人生日相同的比率是9.68
10个人生日相同的比率是11.77
11个人生日相同的比率是14.06
12个人生日相同的比率是17.04
13个人生日相同的比率是20.169999999999998
14个人生日相同的比率是21.790000000000003
15个人生日相同的比率是25.040000000000003
16个人生日相同的比率是28.53
17个人生日相同的比率是30.769999999999996
18个人生日相同的比率是35.160000000000004
19个人生日相同的比率是37.74
20个人生日相同的比率是40.53
21个人生日相同的比率是45.08
22个人生日相同的比率是47.0
23个人生日相同的比率是51.07000000000001
24个人生日相同的比率是52.52
25个人生日相同的比率是57.02
26个人生日相同的比率是60.309999999999995
27个人生日相同的比率是61.85000000000001
28个人生日相同的比率是65.06
29个人生日相同的比率是67.86
30个人生日相同的比率是70.19
31个人生日相同的比率是72.38
32个人生日相同的比率是74.87
33个人生日相同的比率是76.78
34个人生日相同的比率是79.78
35个人生日相同的比率是81.15
应该是’n个人中两个人生日相同的比率‘上面的描述有问题。
1.35
def test_fun(data):
word_punctuation=string.punctuation
# print(string.punctuation)
word_dict={}
for i in word_punctuation:
data=data.replace(i,'') #replace是替换原字符串,并不产生新的对象,
# print(data)
for j in data.split(): #注意这里一定要写函数里面的形参,如果写成str_test
#那也是能取到值的,我说怎么上面的代码测试标点已经去完了
if j not in word_dict: #怎么输出的单词里面又夹杂标点
word_dict[j]=1
else:
word_dict[j]+=1
for k,j in word_dict.items():
print('单词%s有%s个'%(k,j))
# print( '单词{0}有{1}个'.format(k,j)) #两种格式均可
print(test_fun(test_str))
第二种方法,用计数器来处理
import string
from collections import Counter
def test_fun(data):
word_punctuation=string.punctuation
word_dict={}
for i in word_punctuation:
data=data.replace(i,'')
counter=Counter(data.split())
# print(counter,type(counter))#产生的是一个容器对象,里面是字典,可以处理字典的方法
for i in counter.items():
print(i)
print(test_fun(test_str))
花了近十天,将《数据结构与算法python语言实现》(Michael T.Goodrich著)这本书第一章的课后练习题做完了,其间找了不少网上资料,查了不少书籍,看了不少别人的解决,总算大部分都搞明白了,做题过程中总是遇到新的不懂的问题,也都往外尽量拓展,反正收获很大。