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

Posted xiaomingyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法 Python语言实现 第一章练习相关的知识,希望对你有一定的参考价值。

说明:部分代码参考了的文章:https://blog.csdn.net/Harrytsz/article/details/86645857,如果大家阅读时有更好的解法,欢迎沟通交流,共同进步!

 

 巩固

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

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

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

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

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

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

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

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

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

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

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

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

技术图片
  1 # R-1.1
  2 def is_multiple(n: int, m: int):
  3     quotient = n / m
  4     remainder = n % m
  5     if quotient > 1 and remainder == 0:
  6         return True
  7     else:
  8         return False
  9 
 10 
 11 # 更优解
 12 def is_multiple(n, m):
 13     return n % m == 0
 14 
 15 
 16 print(is_multiple(4, 2))
 17 
 18 
 19 # R-1.2
 20 def is_even(k: int):
 21     i = 0
 22     while i < k:
 23         if i + i == k:
 24             return True
 25         i += 1
 26     return False
 27 
 28 
 29 # 更优解
 30 def is_even(k):
 31     k = abs(k)
 32     while k > 1:
 33         k -= 2
 34     return k == 0
 35 
 36 
 37 print(is_even(5))
 38 
 39 
 40 # R-1.3
 41 def minmax(data):
 42     i = a = data[0]
 43     for n in range(len(data)):
 44         if i > data[n]:
 45             i = data[n]
 46         if a < data[n]:
 47             a = data[n]
 48     return i, a
 49 
 50 
 51 # 更优解
 52 def minmax(data):
 53 
 54     minv = data[0]
 55     maxv = data[0]
 56     for item in data:
 57         if minv > item:
 58             minv = item
 59         if maxv < item:
 60             maxv = item
 61     return minv, maxv
 62 
 63 
 64 l = [1, 3, 4, 5, 8, 2, 0]
 65 print(minmax(l))
 66 
 67 
 68 # R-1.4
 69 def sum_square(n):
 70     sum_num = 0
 71     for i in range(n+1):
 72         sum_num += i**2
 73     print(sum_num)
 74 
 75 
 76 sum_square(4)
 77 
 78 
 79 # R-1.5
 80 def sum_of_square2(n):
 81     return sum(i**2 for i in range(n+1))
 82 
 83 
 84 def sum_of_square3(n):
 85     return sum(list(map(lambda x: x**2, range(n+1))))
 86 
 87 
 88 print(sum_of_square3(3))
 89 
 90 
 91 # R-1.6
 92 def odd_square(n):
 93     odd_square_sum = 0
 94     for i in range(1, n+1):
 95         if i % 2:
 96             odd_square_sum += i**2
 97     return odd_square_sum
 98 
 99 
100 print(odd_square(5))
101 
102 
103 # R-1.7
104 n = 5
105 print(sum(i**2 for i in range(n+1) if i % 2))
106 
107 
108 # R-1.8
109 j = n+k
110 
111 
112 # R-1.9
113 print(list(range(50, 81, 10)))
114 
115 
116 # R-1.10
117 l = list(range(8, -9, -2))
118 print(l)
119 
120 
121 # R-1.11
122 # 常规解法
123 i = 1
124 l = []
125 j = 0
126 while j < 9:
127     l.append(i)
128     i *= 2
129     j += 1
130 print(l)
131 
132 # 列表解析式
133 l = [i for i in range(1, 257) if 256 % i == 0]
134 
135 
136 # 更优解
137 l6 = list(map(lambda i: 2**i, range(9)))
138 l7 = [2 ** x for x in range(9)]
139 print(l7)
140 
141 
142 # R-1.12
143 from random import randrange
144 
145 
146 def my_choice(data):
147     while True:
148         r = randrange(min(data), max(data)+1)
149         if r in data:
150             return r
151         else:
152             continue
153 
154 
155 # 更优解
156 def my_choice(data):
157     myrandint = randrange(len(data))
158     return data[myrandint]
159 
160 
161 l = [1, 2, 4, 6, 18, 7]
162 print(my_choice(l))
巩固部分代码参考

 

创新

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

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

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

C-1.16 在1.5.1节 scale 函数的实现中,循环体内执行的命令 data[j] *= factor。我们已经说过这个数字类型是不可变的,操作符 *= 在这种背景下使用是创建一个新的实例(而不是现有实例的变化)。那么 scale 函数是如何实现改变调用者发送的实际参数呢?
C-1.17 1.5.1节 scale 函数的实现如下。它能正常工作吗?请给出原因。

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

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

C-1.20 Python 的 random 模块包括一个函数 shuffle(data),它可以接受一个元素的列表和一个随机的重新排列元素,以使每个可能的序列发生概率相等。 random 模块还包括一个更基本的函数 randint(a, b),它可以返回一个 a 到 b (包括两个端点)的随机整数。只使用 randint 函数,实现自己的 shuffle 函数。
C-1.21 编写一个Python程序,反复从标准输入读取一行直到抛出 EOFError 异常,然后以相反的顺序输出这些行(用户可以通过键按 Ctrl + D 结束输入)。

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

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

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

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

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

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

C-1.28 在 n 维空间定义一个向量 v=(v1,v2,...,vn)v=(v1?,v2?,...,vn?) 的 p 范数, 如下所示:
v=vp1+vp2++vpn−−−−−−−−−−−−−−√p∣∣v∣∣=p√v1p?+v2p?+⋅⋅⋅+vnp??
对于 p = 2 的特殊情况,这就成了传统的欧几里得范数,表示向量的长度。例如,一个二维向量坐标为 (4,3) 的欧几里得范数为 +=√16+9=√25=5。编写 norm 函数,即 norm(v, p),返回向量 v 的 p 范数的值, norm(v),返回向量 v 的欧几里得范数。你可以假定 v 是一个数字列表。

技术图片
  1 import re
  2 from random import shuffle, randint
  3 
  4 
  5 # C-1.13
  6 def my_reverse(data):
  7     new_data = []
  8     for i in range(len(data)-1, -1, -1):
  9         new_data.append(data[i])
 10     return new_data
 11 
 12 
 13 # 更优解
 14 def my_reverse(data):
 15     return data[::-1]
 16 
 17 
 18 l = [1, 2, 3, 5, 6]
 19 new_l = my_reverse(l)
 20 print(new_l)
 21 l.reverse()
 22 print(l)
 23 
 24 
 25 # C-1.14
 26 def confirm_multiply(data):
 27     for i in data:
 28         for j in data:
 29             if i != j and i * j % 2:
 30                 return True
 31     return False
 32 
 33 
 34 # 更优解
 35 def has_odd_mut1(data):
 36     temp = []
 37     for item in data:
 38         if item % 2 and item not in temp:
 39             temp.append(item)
 40     if len(temp) >= 2:
 41         return True
 42     else:
 43         return False
 44 
 45 
 46 def has_odd_mut2(data):
 47     temp = set()
 48     for item in data:
 49         if item % 2:
 50             temp.add(item)
 51     return len(temp) >= 2
 52 
 53 
 54 l = [2, 4, 6, 7, 9]
 55 print(confirm_multiply(l))
 56 
 57 
 58 # C-1.15
 59 def confirm_different_num(data):
 60     for i in range(len(data)):
 61         for j in range(len(data)):
 62             if i != j and data[i] == data[j]:
 63                 return False
 64     return True
 65 
 66 
 67 # 更优解
 68 def is_diff1(data):
 69     temp = set()
 70     for item in data:
 71         if item not in temp:
 72             temp.add(item)
 73         else:
 74             return False
 75     return True
 76 
 77 
 78 def is_diff2(data):
 79     return len(set(data)) == len(data)
 80 
 81 
 82 l15 = [1, 2, 3, 4, 6, 3]
 83 print(confirm_different_num(l15))
 84 
 85 
 86 # C-1.16
 87 通过更改可变序列索引值进行更改
 88 
 89 
 90 # C-1.17
 91 # 不行,不可变类型不可变
 92 def scale(data, factor):
 93     for val in data:
 94         val *= factor
 95     return data
 96 
 97 
 98 l17 = list(range(9))
 99 print(l17)
100 print(scale(l17, 3))
101 
102 
103 # C-1.18
104 l18 = [i*(i+1) for i in range(10)]
105 print(l18)
106 
107 
108 # C-1.19
109 print(chr(97))  # ‘a‘
110 l19 = [chr(i) for i in range(97, 123)]
111 
112 # 更优解
113 l19 = [chr(ord(a) + x) for x in range(26)]
114 print(l19)
115 
116 
117 # C-1.20
118 l20 = [1, 3, 6, 8, 9]
119 shuffle(l20)
120 print(l20)
121 
122 
123 def my_shuffle(data):
124     new_data = []
125     data_copy = data.copy()
126     while data_copy:
127         i = randint(0, len(data_copy)-1)
128         new_data.append(data_copy[i])
129         data_copy.pop(i)
130     return new_data
131 
132 
133 print(my_shuffle(l20))
134 print(l20)
135 
136 
137 # C-1.21
138 content_list = []
139 try:
140     while True:
141         content = input(请输入:)
142         content_list.append(content)
143 except EOFError:
144     while content_list:
145         print(content_list.pop())
146 
147 
148 # C-1.22
149 def point_multiply(a, b):
150     c = []
151     for i in range(len(a)):
152         c.append(a[i]*b[i])
153     return c
154 
155 
156 a_l = [1, 2, 3]
157 b_l = [4, 5, 6]
158 print(point_multiply(a_l, b_l))
159 
160 
161 # C-1.23
162 def confirm_index(data, index):
163     try:
164         return data[index]
165     except IndexError:
166         print("Don‘t try buffer overflow attacks in Python")
167 
168 
169 l23 = [1, 2, 5]
170 confirm_index(l23, 6)
171 
172 
173 # C-1.24
174 def sum_vowel_words(data):
175     sum_num = 0
176     for item in data:
177         if item in [a, e, i, o, u, A, E, I, O, U]:
178             sum_num += 1
179     return sum_num
180 
181 
182 print(sum_vowel_words(abcdefgo))
183 
184 
185 # C-1.25
186 def replace_punctuation(data):
187     new_data = ‘‘
188     for item in data:
189         if item in [,, "", ., !]:
190             item = ‘‘
191         new_data += item
192     return new_data
193 
194 
195 # 更优解
196 def replace_punctuation(data):
197     return re.sub("[‘.,]", ‘‘, data)
198 
199 
200 print(replace_punctuation("Let‘s try, Mike."))
201 
202 
203 # C-1.26
204 def test_calculation():
205     a = int(input(a:))
206     b = int(input(b:))
207     c = int(input(c:))
208     return a + b == c or a == b - c or a * b == c
209 
210 
211 print(test_calculation())
212 
213 
214 # C-1.27
215 def factors(n):
216     k = 1
217     l = []
218     while k * k < n:
219         if n % k == 0:
220             l.append(k)
221             l.append(n // k)
222         k += 1
223     if k * k == n:
224         l.append(k)
225     return sorted(l)
226 
227 
228 # 更优解
229 def factors(n):
230     k = 1
231     temp = []
232     while k * k < n:
233         if n % k == 0:
234             yield k
235             temp.append(n // k)
236         k += 1
237     if k * k == n:
238         yield k
239     for item in temp[::-1]:
240         yield item
241 
242 
243 print(list(factors(100)))
244 
245 
246 # C-1.28
247 def norm(v: list, p: int):
248     sum_num = 0
249     for num in v:
250         sum_num += num ** p
251     return sum_num ** (1/p)
252 
253 
254 print(norm([3, 4], 2))
创新部分代码参考

 

 项目

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

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

P-1.31 编写一个可以“找零钱”的 Python 程序。程序应该将两个数字作为输入,一个是需要支付的钱数,另一个是你给的钱数。当你需要支付的和所给的钱数不同时,它应该返回所找的纸币和硬币的数量。纸币和硬币的值可以基于之前或现在政府的货币体系。试设计程序,以便返回尽可能少的纸币和硬币。
P-1.32 编写一个 Python 程序来模拟一个简单的计算器,使用控制台作为输入和输出的专用设备。也就是说,计算器的每一次输入做一个单独的行,它可以输入一个数字(如1034或12.34)或操作符(如 + 或 = )。每一次输入后,应该输出计算器显示的结果并将其输出到 Python 控制台。

P-1.33 编写一个 Python 程序来模拟一个手持计算器,程序应该可以处理来自 Python 控制台(表示 Push 按钮)的输入,每个操作执行完毕后内容输出到屏幕。计算器至少应该能够处理基本的算术运算和复位/清除操作。

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

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

技术图片

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

技术图片
  1 # P-1.29 编写一个 Python 程序,输出由字母 ‘c’,‘a’,‘t’,‘d’,‘o’,‘g’ 组成的所有可能的字符串(每个字母只使用1次)。
  2 
  3 # 本人做题思路:因为原来不知道python排列函数permutations,故自己算出6个字母有6!=720中排列方式,采用shuffle函数加上集合去重的方法.
  4 from random import shuffle
  5 
  6 
  7 words = [c, a, t, d, o, g]
  8 new_words_set = set()
  9 while len(new_words_set) < 720:
 10     new_words = shuffle(words)
 11     word = ‘‘.join(words)
 12     new_words_set.add(word)
 13 # print(new_words_set)
 14 
 15 
 16 # 更优解
 17 from itertools import permutations
 18 
 19 
 20 def function29():
 21     words_list = [c, a, t, d, o, g]
 22     new_word = list(map(‘‘.join, permutations(words_list)))
 23     return new_word
 24 
 25 
 26 # print(function29())
 27 # print(len(function29()))
 28 
 29 
 30 # 用Python实现排列和组合
 31 def combinations(iterable, r):  # iterable=[1, 2, 3, 4]  r = 2
 32     pool = tuple(iterable)  # pool = (1, 2, 3, 4)
 33     n = len(iterable)  # n = 4
 34     if r > n:
 35         return
 36     indices = list(range(r))  # indices = [0, 1]
 37     yield tuple(pool[i] for i in indices)  # yield (1, 2)
 38     while True:
 39         for i in reversed(range(r)):  # for i in [1, 0]
 40             if indices[i] != i + n - r:
 41                 break
 42         else:
 43             return
 44         indices[i] += 1  # indices = 1[0, 2] 2[0, 3] #3[1, 3] 5[1, 3] #6[2, 3]
 45         print(indice[i], indices)
 46         for j in range(i + 1, r):
 47             indices[j] = indices[j - 1] + 1  # indices = 4[1, 2]  7[2, 3]
 48             print(indices[j], indices)
 49         yield tuple(pool[i] for i in indices)  # yield(1, 3) (1, 4) (2, 3) (2, 4) (3, 4)
 50 
 51 
 52 # print(list(combinations([1, 2, 3, 4], r=2)))
 53 
 54 
 55 def permutations(iterable, r=None):
 56     pool = tuple(iterable)
 57     n = len(iterable)
 58     r = n if r is None else r
 59     if r > n:
 60         return
 61     indices = list(range(n))
 62     cycles = list(range(n, n - r, -1))
 63     yield tuple(pool[i] for i in indices[:r])
 64     while n:
 65         for i in reversed(range(r)):
 66             cycles[i] -= 1
 67             if cycles[i] == 0:
 68                 indices[i:] = indices[i + 1:] + indices[i:i + 1]
 69                 cycles[i] = n - i
 70             else:
 71                 j = cycles[i]
 72                 indices[i], indices[-j] = indices[-j], indices[i]
 73                 yield tuple(pool[i] for i in indices[:r])
 74                 break
 75         else:
 76             return
 77 
 78 # print(list(permutations([1, 2, 3])))
 79 
 80 
 81 # P-1.30
 82 def divide_two_times():
 83 
 84     quotient = int(input(请输入一个数字:
))
 85     times = 0
 86     while quotient > 2:
 87         quotient = quotient / 2
 88         times += 1
 89     return times
 90 
 91 
 92 # divide_two_times()
 93 
 94 
 95 # P-1.31
 96 def change_function(price, payment):
 97     currency = [100, 50, 20, 10, 5, 1, 0.5, 0.1]
 98     change_list = []
 99     change_amount = payment - price
100     indices = list(range(len(currency)))
101     while change_amount >= 0.1:
102         for i in indices[1:]:
103             if currency[i] <= change_amount < currency[i-1]:
104                 change_list.append(currency[i])
105                 change_amount -= currency[i]
106     return change_list
107 
108 
109 # print(change_function(10.82, 100))
110 # print(1-0.8)
111 
112 
113 # P-1.32
114 s = ‘‘
115 while True:
116     input_num = input(请输入:)
117     if input_num != =:
118         s += input_num
119     else:
120         print(eval(s))
121         s = ‘‘
122 
123 
124 # 参考解法
125 def function32():
126     temp = input(Please input Number1 Operation Numbers2: 
).split(" ")
127     num1 = int(temp[0])
128     num2 = int(temp[2])
129     oper = str(temp[1])
130 
131     if oper == +:
132         result = num1 + num2
133     elif oper == -:
134         result = num1 - num2
135     elif oper == *:
136         result = num1 * num2
137     elif oper == /:
138         result = num1 / num2
139     else:
140         raise EOFError(Error Input!)
141     print(result)
142 
143 
144 # function32()
145 
146 
147 # P-1.33
148 s = ‘‘
149 while True:
150     input_num = input(请输入:)
151     if input_num != =:
152         s += input_num
153     else:
154         print(eval(s))
155         s = ‘‘
156 
157 
158 # P-1.34
159 num = 0
160 while num < 100:
161     input_data = input(已抄写%s遍请输入: % num)
162     if input_data == I will never spam my friends again.:
163         num += 1
164 print(恭喜抄完!!!)
165 
166 
167 # P-1.35
168 # 此方法是直观的观测生日有相同的概率,不能做定量计算
169 from random import randint
170 
171 
172 def test_birthday(n):
173     birthday_list = []
174     while len(birthday_list) < n:
175         birthday = randint(1, 365)
176         birthday_list.append(birthday)
177     if len(set(birthday_list)) < len(birthday_list):
178         print(True)
179     return birthday_list
180 
181 
182 # print(test_birthday(23))
183 
184 
185 # 参考解法
186 def function35(num):
187     import math
188     from decimal import Decimal
189     prop = 1 - Decimal((math.factorial(365)))/Decimal((math.pow(365, num) * math.factorial(364 - num)))
190     return prop
191 
192 
193 def function352(num):
194     import math
195     prop = 1 - math.pow((364/365), (num*(num-1)/2))
196     return prop
197 
198 
199 print(function352(23))  # 0.5004771540365807
200 
201 
202 # P-1.36
203 def words_statistic(data: list):
204     words_dict = {}
205     for words in data:
206         if words not in words_dict:
207             words_dict[words] = 1
208         else:
209             words_dict[words] += 1
210     return words_dict
211 
212 
213 # print(words_statistic([‘hello‘, ‘hi‘, ‘world‘, ‘hi‘, ‘world‘, ‘hi‘]))
214 # 更优解
215 def function36():
216     temp = input(请输入英语单词: 
).split( )
217     keys = list(set(temp))
218     result = dict(zip(keys, [0]*len(keys)))
219     for item in temp:
220         result[item] += 1
221     return result
222 
223 
224 function36()
项目部分代码参考

以上是关于数据结构与算法 Python语言实现 第一章练习的主要内容,如果未能解决你的问题,请参考以下文章

python第一章练习题

《算法图解》第一章笔记与课后练习

第一章练习题作业

数据结构与算法 Python语言实现 第四章练习

数据结构与算法 Python语言实现 第三章练习

第一章练习题