数据结构与算法 Python语言实现 第一章练习
说明:部分代码参考了Harrytsz的文章: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 函数。
# R-1.1
def is_multiple(n: int, m: int):
quotient = n / m
remainder = n % m
if quotient > 1 and remainder == 0:
return True
else:
return False # 更优解
def is_multiple(n, m):
return n % m == 0 print(is_multiple(4, 2)) # R-1.2
def is_even(k: int):
i = 0
while i < k:
if i + i == k:
return True
i += 1
return False # 更优解
def is_even(k):
k = abs(k)
while k > 1:
k -= 2
return k == 0 print(is_even(5)) # R-1.3
def minmax(data):
i = a = data[0]
for n in range(len(data)):
if i > data[n]:
i = data[n]
if a < data[n]:
a = data[n]
return i, a # 更优解
def minmax(data): minv = data[0]
maxv = data[0]
for item in data:
if minv > item:
minv = item
if maxv < item:
maxv = item
return minv, maxv l = [1, 3, 4, 5, 8, 2, 0]
print(minmax(l)) # R-1.4
def sum_square(n):
sum_num = 0
for i in range(n+1):
sum_num += i**2
print(sum_num) sum_square(4) # R-1.5
def sum_of_square2(n):
return sum(i**2 for i in range(n+1)) def sum_of_square3(n):
return sum(list(map(lambda x: x**2, range(n+1)))) print(sum_of_square3(3)) # R-1.6
def odd_square(n):
odd_square_sum = 0
for i in range(1, n+1):
if i % 2:
odd_square_sum += i**2
return odd_square_sum print(odd_square(5)) # R-1.7
n = 5
print(sum(i**2 for i in range(n+1) if i % 2)) # R-1.8
j = n+k # R-1.9
print(list(range(50, 81, 10))) # R-1.10
l = list(range(8, -9, -2))
print(l) # R-1.11
# 常规解法
i = 1
l = []
j = 0
while j < 9:
l.append(i)
i *= 2
j += 1
print(l) # 列表解析式
l = [i for i in range(1, 257) if 256 % i == 0] # 更优解
l6 = list(map(lambda i: 2**i, range(9)))
l7 = [2 ** x for x in range(9)]
print(l7) # R-1.12
from random import randrange def my_choice(data):
while True:
r = randrange(min(data), max(data)+1)
if r in data:
return r
else:
continue # 更优解
def my_choice(data):
myrandint = randrange(len(data))
return data[myrandint] l = [1, 2, 4, 6, 18, 7]
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) 的欧几里得范数为 √4²+3²=√16+9=√25=5。编写 norm 函数,即 norm(v, p),返回向量 v 的 p 范数的值, norm(v),返回向量 v 的欧几里得范数。你可以假定 v 是一个数字列表。
import re
from random import shuffle, randint # C-1.13
def my_reverse(data):
new_data = []
for i in range(len(data)-1, -1, -1):
new_data.append(data[i])
return new_data # 更优解
def my_reverse(data):
return data[::-1] l = [1, 2, 3, 5, 6]
new_l = my_reverse(l)
print(new_l)
l.reverse()
print(l) # C-1.14
def confirm_multiply(data):
for i in data:
for j in data:
if i != j and i * j % 2:
return True
return False # 更优解
def has_odd_mut1(data):
temp = []
for item in data:
if item % 2 and item not in temp:
temp.append(item)
if len(temp) >= 2:
return True
else:
return False def has_odd_mut2(data):
temp = set()
for item in data:
if item % 2:
temp.add(item)
return len(temp) >= 2 l = [2, 4, 6, 7, 9]
print(confirm_multiply(l)) # C-1.15
def confirm_different_num(data):
for i in range(len(data)):
for j in range(len(data)):
if i != j and data[i] == data[j]:
return False
return True # 更优解
def is_diff1(data):
temp = set()
for item in data:
if item not in temp:
temp.add(item)
else:
return False
return True def is_diff2(data):
return len(set(data)) == len(data) l15 = [1, 2, 3, 4, 6, 3]
print(confirm_different_num(l15)) # C-1.16
通过更改可变序列索引值进行更改 # C-1.17
# 不行,不可变类型不可变
def scale(data, factor):
for val in data:
val *= factor
return data l17 = list(range(9))
print(l17)
print(scale(l17, 3)) # C-1.18
l18 = [i*(i+1) for i in range(10)]
print(l18) # C-1.19
print(chr(97)) # 'a'
l19 = [chr(i) for i in range(97, 123)] # 更优解
l19 = [chr(ord('a') + x) for x in range(26)]
print(l19) # C-1.20
l20 = [1, 3, 6, 8, 9]
shuffle(l20)
print(l20) def my_shuffle(data):
new_data = []
data_copy = data.copy()
while data_copy:
i = randint(0, len(data_copy)-1)
new_data.append(data_copy[i])
data_copy.pop(i)
return new_data print(my_shuffle(l20))
print(l20) # C-1.21
content_list = []
try:
while True:
content = input('请输入:')
content_list.append(content)
except EOFError:
while content_list:
print(content_list.pop()) # C-1.22
def point_multiply(a, b):
c = []
for i in range(len(a)):
c.append(a[i]*b[i])
return c a_l = [1, 2, 3]
b_l = [4, 5, 6]
print(point_multiply(a_l, b_l)) # C-1.23
def confirm_index(data, index):
try:
return data[index]
except IndexError:
print("Don't try buffer overflow attacks in Python") l23 = [1, 2, 5]
confirm_index(l23, 6) # C-1.24
def sum_vowel_words(data):
sum_num = 0
for item in data:
if item in ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']:
sum_num += 1
return sum_num print(sum_vowel_words('abcdefgo')) # C-1.25
def replace_punctuation(data):
new_data = ''
for item in data:
if item in [',', "'", '.', '!']:
item = ''
new_data += item
return new_data # 更优解
def replace_punctuation(data):
return re.sub("['.,]", '', data) print(replace_punctuation("Let's try, Mike.")) # C-1.26
def test_calculation():
a = int(input('a:'))
b = int(input('b:'))
c = int(input('c:'))
return a + b == c or a == b - c or a * b == c print(test_calculation()) # C-1.27
def factors(n):
k = 1
l = []
while k * k < n:
if n % k == 0:
l.append(k)
l.append(n // k)
k += 1
if k * k == n:
l.append(k)
return sorted(l) # 更优解
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 print(list(factors(100))) # C-1.28
def norm(v: list, p: int):
sum_num = 0
for num in v:
sum_num += num ** p
return sum_num ** (1/p) 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程序,输入一个由空格分隔的单词列表,并输出列表中的每个单词出现的次数。在这一点上,你不需要担心效率,因为这个问题会在本书后面的部分予以解决。
# P-1.29 编写一个 Python 程序,输出由字母 ‘c’,‘a’,‘t’,‘d’,‘o’,‘g’ 组成的所有可能的字符串(每个字母只使用1次)。 # 本人做题思路:因为原来不知道python排列函数permutations,故自己算出6个字母有6!=720中排列方式,采用shuffle函数加上集合去重的方法.
from random import shuffle words = ['c', 'a', 't', 'd', 'o', 'g']
new_words_set = set()
while len(new_words_set) < 720:
new_words = shuffle(words)
word = ''.join(words)
new_words_set.add(word)
# print(new_words_set) # 更优解
from itertools import permutations def function29():
words_list = ['c', 'a', 't', 'd', 'o', 'g']
new_word = list(map(''.join, permutations(words_list)))
return new_word # print(function29())
# print(len(function29())) # 用Python实现排列和组合
def combinations(iterable, r): # iterable=[1, 2, 3, 4] r = 2
pool = tuple(iterable) # pool = (1, 2, 3, 4)
n = len(iterable) # n = 4
if r > n:
return
indices = list(range(r)) # indices = [0, 1]
yield tuple(pool[i] for i in indices) # yield (1, 2)
while True:
for i in reversed(range(r)): # for i in [1, 0]
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1 # indices = 1[0, 2] 2[0, 3] #3[1, 3] 5[1, 3] #6[2, 3]
print('indice[i]', indices)
for j in range(i + 1, r):
indices[j] = indices[j - 1] + 1 # indices = 4[1, 2] 7[2, 3]
print('indices[j]', indices)
yield tuple(pool[i] for i in indices) # yield(1, 3) (1, 4) (2, 3) (2, 4) (3, 4) # print(list(combinations([1, 2, 3, 4], r=2))) def permutations(iterable, r=None):
pool = tuple(iterable)
n = len(iterable)
r = n if r is None else r
if r > n:
return
indices = list(range(n))
cycles = list(range(n, n - r, -1))
yield tuple(pool[i] for i in indices[:r])
while n:
for i in reversed(range(r)):
cycles[i] -= 1
if cycles[i] == 0:
indices[i:] = indices[i + 1:] + indices[i:i + 1]
cycles[i] = n - i
else:
j = cycles[i]
indices[i], indices[-j] = indices[-j], indices[i]
yield tuple(pool[i] for i in indices[:r])
break
else:
return # print(list(permutations([1, 2, 3]))) # P-1.30
def divide_two_times(): quotient = int(input('请输入一个数字:\n'))
times = 0
while quotient > 2:
quotient = quotient / 2
times += 1
return times # divide_two_times() # P-1.31
def change_function(price, payment):
currency = [100, 50, 20, 10, 5, 1, 0.5, 0.1]
change_list = []
change_amount = payment - price
indices = list(range(len(currency)))
while change_amount >= 0.1:
for i in indices[1:]:
if currency[i] <= change_amount < currency[i-1]:
change_list.append(currency[i])
change_amount -= currency[i]
return change_list # print(change_function(10.82, 100))
# print(1-0.8) # P-1.32
s = ''
while True:
input_num = input('请输入:')
if input_num != '=':
s += input_num
else:
print(eval(s))
s = '' # 参考解法
def function32():
temp = input('Please input Number1 Operation Numbers2: \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!')
print(result) # function32() # P-1.33
s = ''
while True:
input_num = input('请输入:')
if input_num != '=':
s += input_num
else:
print(eval(s))
s = '' # P-1.34
num = 0
while num < 100:
input_data = input('已抄写%s遍请输入:' % num)
if input_data == 'I will never spam my friends again.':
num += 1
print('恭喜抄完!!!') # P-1.35
# 此方法是直观的观测生日有相同的概率,不能做定量计算
from random import randint def test_birthday(n):
birthday_list = []
while len(birthday_list) < n:
birthday = randint(1, 365)
birthday_list.append(birthday)
if len(set(birthday_list)) < len(birthday_list):
print(True)
return birthday_list # print(test_birthday(23)) # 参考解法
def function35(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 function352(num):
import math
prop = 1 - math.pow((364/365), (num*(num-1)/2))
return prop print(function352(23)) # 0.5004771540365807 # P-1.36
def words_statistic(data: list):
words_dict = {}
for words in data:
if words not in words_dict:
words_dict[words] = 1
else:
words_dict[words] += 1
return words_dict # print(words_statistic(['hello', 'hi', 'world', 'hi', 'world', 'hi']))
# 更优解
def function36():
temp = input('请输入英语单词: \n').split(' ')
keys = list(set(temp))
result = dict(zip(keys, [0]*len(keys)))
for item in temp:
result[item] += 1
return result function36()
项目部分代码参考
数据结构与算法 Python语言实现 第一章练习的更多相关文章
- 读书笔记《数据结构与算法JavaScript描述》第一章
第一章JavaScript的编程环境和模型 1.2JavaScript编程实践 1.2.1 声明和初始化变量 JavaScript中的变量默认为全局变量,如果初始化未被声明的变量,该变量就成了一个全局 ...
- 《数据结构与算法Python语言描述》习题第二章第一题(python版)
题目:定义一个表示时间的类Timea)Time(hours,minutes,seconds)创建一个时间对象:b)t.hours(),t.minutes(),t.seconds()分别返回时间对象t的 ...
- 《数据结构与算法Python语言描述》习题第二章第三题(python版)
ADT Rational: #定义有理数的抽象数据类型 Rational(self, int num, int den) #构造有理数num/den +(self, Rational r2) #求出本 ...
- 《数据结构与算法Python语言描述》习题第二章第二题(python版)
ADT Date: #定义日期对象的抽象数据类型 Date(self, int year, int month, int day) #构造表示year/month/day的对象 difference( ...
- 数据结构与算法-Python/C(目录)
第一篇 基本概念 01 什么是数据结构 02 什么是算法 03 应用实例-最大子列和问题 第二篇 线性结构 01 线性表及其实现 02 堆栈 03 队列 04 应用实例-多项式加法运算 05 小白专场 ...
- 北京大学公开课《数据结构与算法Python版》
之前我分享过一个数据结构与算法的课程,很多小伙伴私信我问有没有Python版. 看了一些公开课后,今天特向大家推荐北京大学的这门课程:<数据结构与算法Python版>. 课程概述 很多同学 ...
- 【数据结构与算法Python版学习笔记】引言
学习来源 北京大学-数据结构与算法Python版 目标 了解计算机科学.程序设计和问题解决的基本概念 计算机科学是对问题本身.问题的解决.以及问题求解过程中得出的解决方案的研究.面对一 个特定问题,计 ...
- 列表的实现-----数据结构与算法JavaScript描述 第三章
实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...
- 数据结构(Java语言描述)-第一章:概述
第一章 概述 1.0 序言 自己为啥要学数据结构嘞,我觉得主要有以下三个原因: 前段时间在看并发编程时,发现aqs,corrunthashmap等底层都用到了数据结构,主要的有队列,还有链表,学习数据 ...
随机推荐
- [转]Springboot和SpringMVC区别
spring boot只是一个配置工具,整合工具,辅助工具. springmvc是框架,项目中实际运行的代码 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等 ...
- 【u128】又一个数字游戏
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小明拿出了一个素数集合,{2, 3, 5, 7, 11, 13, -, 127, -},他发现,从小到 ...
- HDU 3974 Assign the task
Assign the task Problem Description There is a company that has N employees(numbered from 1 to N),ev ...
- H3C擦除配置
- activiti工作流引擎学习(三)
5.接收任务活动(receiveTask,即等待活动)不是一个任务节点 接收任务是一个简单任务,他会等待回应消息的到达,当前,官方只实现了这个任务的java语义,当流程达到接受任务,流程状态会保存到数 ...
- VS code 汉化及快捷键修改
VsCode汉化方式 Vscode是一款开源的跨平台编辑器.默认情况下,vscode使用的语言为英文(us),如何将其显示语言修改成中文了? 打开vscode工具: 点击左侧的Extensions(拓 ...
- "技术框架太多,多的眼花缭乱,如何在众多选择中找到自己的方向?
"技术框架太多,多的眼花缭乱,如何在众多选择中找到自己的方向?",经常有人这么问我. 咱们从开源项目说起,可以从两个维度来对开源项目进行分类,一方面是编程语言,另一方面是应用领域. ...
- .net core 读取Excal文件数据及注意事项
添加ExcelDataReader.DataSet引用. 调用下列方法: public class XlsHelper { public static System.Data.DataSet GetX ...
- 用VISA工具驱动继电器外设
1.驱动方式:TCP 2.开发过程 第一步:外设识别 TCP方式将继电器插上网线后,并不能像串口一样自动识别到这个外设,需要手动连接.打开NI MAX后,右击设备与接口,然后点击新建,双击VISA T ...
- Docker Desktop for Windows Experience
Docker Desktop for Windows Experience: https://github.com/poazy/boazy-learn/blob/master/doc/Docker%2 ...