递归算法与编程练习详解
1. 北约音标字母表
北约音标字母表是一种用单词代表字母的标准,方便在通信中准确传达字母信息。以下是其详细内容:
| Letter | Word | Letter | Word | Letter | Word |
| ---- | ---- | ---- | ---- | ---- | ---- |
| A | Alpha | J | Juliet | S | Sierra |
| B | Bravo | K | Kilo | T | Tango |
| C | Charlie | L | Lima | U | Uniform |
| D | Delta | M | Mike | V | Victor |
| E | Echo | N | November | W | Whiskey |
| F | Foxtrot | O | Oscar | X | Xray |
| G | Golf | P | Papa | Y | Yankee |
| H | Hotel | Q | Quebec | Z | Zulu |
| I | India | R | Romeo | | |
2. 递归编程练习
2.1 罗马数字转整数
罗马数字由字母 M、D、C、L、X、V 和 I 组成,分别代表 1000、500、100、50、10、5 和 1。一般从大到小书写,若小值在大值前,则从大值中减去小值。
以下是实现罗马数字转整数的递归函数思路:
1. 处理字符串开头的一到两个字符。
2. 递归调用自身处理未处理的字符。
3. 空字符串值为 0,作为基本情况。
# 此处可根据上述思路编写具体代码
2.2 递归判断回文串
空字符串和单字符字符串是回文串,长字符串若首尾字符相同且去掉首尾字符后的子串也是回文串,则该长字符串是回文串。
判断回文串的递归函数步骤如下:
1. 读取用户输入的字符串。
2. 使用递归函数判断是否为回文串。
3. 显示相应信息。
# 此处可根据上述步骤编写具体代码
2.3 递归计算平方根
使用递归方法计算平方根,通过不断逼近的策略。
计算平方根的递归函数参数:
1.
n
:要计算平方根的数。
2.
guess
:当前的平方根猜测值,默认值为 1.0。
递归函数的基本情况:当
guess
的平方与
n
的差值在 $10^{-12}$ 以内时,返回
guess
。
否则,递归调用自身,新的猜测值为
(guess + n / guess) / 2
。
# 此处可根据上述内容编写具体代码
2.4 字符串编辑距离
编辑距离衡量两个字符串的相似度,通过插入、删除和替换操作将一个字符串转换为另一个字符串所需的最小操作数。
计算编辑距离的递归算法如下:
1. 设
s
和
t
为两个字符串。
2. 若
s
的长度为 0,返回
t
的长度。
3. 若
t
的长度为 0,返回
s
的长度。
4. 否则:
- 初始化
cost
为 0。
- 若
s
的最后一个字符不等于
t
的最后一个字符,
cost
设为 1。
- 计算
d1
:
s
除最后一个字符外与
t
的编辑距离加 1。
- 计算
d2
:
s
与
t
除最后一个字符外的编辑距离加 1。
- 计算
d3
:
s
除最后一个字符外与
t
除最后一个字符外的编辑距离加
cost
。
- 返回
d1
、
d2
和
d3
中的最小值。
# 此处可根据上述算法编写具体代码
3. 其他递归编程问题
3.1 硬币组合问题
判断是否可以用指定数量的硬币组成特定的总金额,假设存在 25 美分(quarter)、10 美分(dime)、5 美分(nickel)和 1 美分(penny)的硬币。
解决该问题的步骤如下:
1. 读取用户输入的美元金额和硬币数量。
2. 使用递归方法判断是否可以组成该金额。
3. 显示清晰的信息。
# 此处可根据上述步骤编写具体代码
3.2 用元素符号拼写单词
判断一个单词是否可以仅用化学元素符号拼写。
实现该功能的递归函数参数:
1. 要拼写的单词。
2. 可用的元素符号列表。
函数返回用于拼写的符号字符串,若无法拼写则返回空字符串。
# 此处可根据上述参数和要求编写具体代码
3.3 化学元素序列游戏
构建一个化学元素序列,每个元素以其前一个元素的最后一个字母开头,且序列中不能有重复元素。
解决该问题的步骤如下:
1. 读取用户输入的元素名称。
2. 使用递归函数找到以该元素开头的最长序列。
3. 显示序列。
# 此处可根据上述步骤编写具体代码
4. 列表处理与编码问题
4.1 扁平化嵌套列表
Python 列表可嵌套,扁平化列表是将多层嵌套列表转换为无嵌套的列表。
扁平化列表的递归算法流程如下:
graph TD;
A[判断 data 是否为空] -->|是| B[返回空列表];
A -->|否| C[判断 data 第一个元素是否为列表];
C -->|是| D[扁平化第一个元素得到 l1];
C -->|否| E[创建仅含第一个元素的列表 l1];
D --> F[扁平化除第一个元素外的元素得到 l2];
E --> F;
F --> G[返回 l1 和 l2 的拼接结果];
# 此处可根据上述算法编写具体代码
4.2 游程编码与解码
游程编码是一种简单的数据压缩技术,将重复值替换为一个值和重复次数。
游程解码的递归函数:
1. 接收游程编码的列表作为唯一参数。
2. 返回解码后的列表。
# 此处可根据上述要求编写具体代码
游程编码的递归函数:
1. 接收列表或字符串作为唯一参数。
2. 返回游程编码后的列表。
# 此处可根据上述要求编写具体代码
5. 编程练习解答
5.1 邮寄地址显示
print("Ben Stephenson")
print("Department of Computer Science")
print("University of Calgary")
print("2500 University Drive NW")
print("Calgary, Alberta T2N 1N4")
print("Canada")
5.2 房间面积计算
# Read the dimensions from the user
length = float(input("Enter the length of the room in feet: "))
width = float(input("Enter the width of the room in feet: "))
# Compute the area of the room
area = length * width
# Display the result
print("The area of the room is", area, "square feet")
5.3 田地面积计算(以英亩为单位)
SQFT_PER_ACRE = 43560
# Read the dimensions from the user
length = float(input("Enter the length of the field in feet: "))
width = float(input("Enter the width of the field in feet: "))
# Compute the area in acres
acres = length * width / SQFT_PER_ACRE
# Display the result
print("The area of the field is", acres, "acres")
5.4 瓶子押金退款计算
LESS_DEPOSIT = 0.10
MORE_DEPOSIT = 0.25
# Read the number of containers of each size from the user
less = int(input("How many containers 1 litre or less? "))
more = int(input("How many containers more than 1 litre? "))
# Compute the refund amount
refund = less * LESS_DEPOSIT + more * MORE_DEPOSIT
# Display the result
print("Your total refund will be $%.2f." % refund)
5.5 餐厅餐费税和小费计算
TAX_RATE = 0.05
TIP_RATE = 0.18
# Read the cost of the meal from the user
cost = float(input("Enter the cost of the meal: "))
# Compute the tax and the tip
tax = cost * TAX_RATE
tip = cost * TIP_RATE
total = cost + tax + tip
# Display the result
print("The tax is %.2f and the tip is %.2f, making the", \
"total %.2f" % (tax, tip, total))
5.6 前 n 个正整数求和
# Read the value of n from the user
n = int(input("Enter a positive integer: "))
# Compute the sum
sm = n * (n + 1) / 2
# Display the result
print("The sum of the first", n, "positive integers is", sm)
5.7 数学运算演示
from math import log10
# Read the input values from the user
a = int(input("Enter the value of a: "))
b = int(input("Enter the value of b: "))
# Compute and display the sum, difference, product, quotient and remainder
print(a, "+", b, "is", a + b)
print(a, "-", b, "is", a - b)
print(a, "*", b, "is", a * b)
print(a, "/", b, "is", a / b)
print(a, "%", b, "is", a % b)
# Compute the logarithm and the power
print("The base 10 logarithm of", a, "is", log10(a))
print(a, "ˆ", b, "is", a**b)
5.8 找零计算
CENTS_PER_TOONIE = 200
CENTS_PER_LOONIE = 100
CENTS_PER_QUARTER = 25
CENTS_PER_DIME = 10
CENTS_PER_NICKEL = 5
# Read the number of cents from the user
cents = int(input("Enter the number of cents: "))
# Determine the number of toonies
print(" ", cents // CENTS_PER_TOONIE, "toonies")
cents = cents % CENTS_PER_TOONIE
# Repeat for loonies, quarters, dimes, and nickels
print(" ", cents // CENTS_PER_LOONIE, "loonies")
cents = cents % CENTS_PER_LOONIE
print(" ", cents // CENTS_PER_QUARTER, "quarters")
cents = cents % CENTS_PER_QUARTER
print(" ", cents // CENTS_PER_DIME, "dimes")
cents = cents % CENTS_PER_DIME
print(" ", cents // CENTS_PER_NICKEL, "nickels")
cents = cents % CENTS_PER_NICKEL
# Display the number of pennies
print(" ", cents, "pennies")
5.9 英尺英寸转厘米
IN_PER_FT = 12
CM_PER_IN = 2.54
# Read the height from the user
print("Enter your height:")
feet = int(input(" Number of feet: "))
inches = int(input(" Number of inches: "))
# Compute the equivalent number of centimeters
cm = (feet * IN_PER_FT + inches) * CM_PER_IN
# Display the result
print("Your height in centimeters is:", cm)
5.10 水加热能量与成本计算
WATER_HEAT_CAPACITY = 4.186
ELECTRICITY_PRICE = 8.9
J_TO_KWH = 2.777e-7
# Read the volume and temperature increase from the user
volume = float(input("Amount of water in milliliters: "))
d_temp = float(input("Temperature increase (degrees Celsius): "))
# Compute the energy in Joules
q = volume * d_temp * WATER_HEAT_CAPACITY
# Display the result in Joules
print("That will require %d Joules of energy." % q)
# Compute the cost
kwh = q * J_TO_KWH
cost = kwh * ELECTRICITY_PRICE
# Display the cost
print("That much energy will cost %.2f cents." % cost)
5.11 自由落体速度计算
from math import sqrt
# Define a constant for the acceleration due to gravity in m/s**2
GRAVITY = 9.8
# Read the height from which the object is dropped
d = float(input("Height (in meters): "))
# Compute the final velocity
vf = sqrt(2 * GRAVITY * d)
# Display the result
print("It will hit the ground at %.2f m/s." % vf)
5.12 正多边形面积计算
from math import tan, pi
# Read input from the user
s = float(input("Enter the length of each side: "))
n = int(input("Enter the number of sides: "))
# Compute the area of the polygon
area = (n * s ** 2) / (4 * tan(pi / n))
# Display the result
print("The area of the polygon is", area)
5.13 秒转换为天、小时、分钟和秒
SECONDS_PER_DAY = 86400
SECONDS_PER_HOUR = 3600
SECONDS_PER_MINUTE = 60
# Read the duration from the user in seconds
seconds = int(input("Enter a number of seconds: "))
# Compute the days, hours, minutes and seconds
days = seconds / SECONDS_PER_DAY
seconds = seconds % SECONDS_PER_DAY
hours = seconds / SECONDS_PER_HOUR
seconds = seconds % SECONDS_PER_HOUR
minutes = seconds / SECONDS_PER_MINUTE
seconds = seconds % SECONDS_PER_MINUTE
# Display the result with the desired formatting
print("The equivalent duration is", \
"%d:%02d:%02d:%02d." % (days, hours, minutes, seconds))
5.14 风寒指数计算
WC_OFFSET = 13.12
WC_FACTOR1 = 0.6215
WC_FACTOR2 = -11.37
WC_FACTOR3 = 0.3965
WC_EXPONENT = 0.16
# Read the air temperature and wind speed from the user
temp = float(input("Air temperature (degrees Celsius): "))
speed = float(input("Wind speed (kilometers per hour): "))
# Compute the wind chill index
wci = WC_OFFSET + \
WC_FACTOR1 * temp + \
WC_FACTOR2 * speed ** WC_EXPONENT + \
WC_FACTOR3 * temp * speed ** WC_EXPONENT
# Display the result rounded to the closest integer
print("The wind chill index is", round(wci))
5.15 三个整数排序
# Read the numbers from the user, naming them a, b and c
a = int(input("Enter the first number: "))
b = int(input("Enter the second number: "))
c = int(input("Enter the third number: "))
mn = min(a, b, c)
mx = max(a, b, c)
md = a + b + c - mn - mx
# Display the result
print("The numbers in sorted order are:")
print(" ", mn)
print(" ", md)
print(" ", mx)
5.16 陈面包价格计算
BREAD_PRICE = 3.49
DISCOUNT_RATE = 0.60
# Read the number of loaves from the user
num_loaves = int(input("Enter the number of day old loaves: "))
# Compute the discount and total price
regular_price = num_loaves * BREAD_PRICE
discount = regular_price * DISCOUNT_RATE
total = regular_price - discount
# Display the result
print("Regular price: %5.2f" % regular_price)
print("Discount: %5.2f" % discount)
print("Total: %5.2f" % total)
递归算法与编程练习详解
6. 递归编程练习总结
在前面的内容中,我们探讨了多个递归编程练习,下面对这些练习进行总结:
| 练习名称 | 主要思路 | 关键代码要点 |
| ---- | ---- | ---- |
| 罗马数字转整数 | 处理字符串开头字符,递归处理剩余部分,空字符串为基本情况 | 递归调用处理字符,根据规则计算数值 |
| 递归判断回文串 | 空串和单字符串是回文串,长串需首尾相同且子串为回文串 | 递归判断首尾字符及子串 |
| 递归计算平方根 | 通过不断逼近策略,以
guess
平方与
n
差值在 $10^{-12}$ 内为基本情况 | 递归更新
guess
值 |
| 字符串编辑距离 | 根据字符串长度和字符比较结果递归计算 | 计算不同情况的编辑距离并取最小值 |
| 硬币组合问题 | 读取金额和硬币数量,递归判断是否可组成金额 | 递归尝试不同硬币组合 |
| 用元素符号拼写单词 | 接收单词和符号列表,返回拼写符号串或空串 | 递归查找可用符号 |
| 化学元素序列游戏 | 读取元素名称,递归找最长序列 | 递归构建元素序列 |
| 扁平化嵌套列表 | 根据列表元素情况递归扁平化 | 递归处理列表元素 |
| 游程编码与解码 | 编码将重复值替换为值和次数,解码反之 | 递归处理编码和解码过程 |
7. 编程练习的应用场景
这些编程练习在实际应用中有广泛的场景:
-
罗马数字转整数
:在处理历史文献、老式钟表等涉及罗马数字的场景中,可将其转换为现代数字进行计算和处理。
-
递归判断回文串
:在文本处理、密码验证等领域,可用于判断字符串是否具有回文特性。
-
递归计算平方根
:在科学计算、图形处理等需要精确计算平方根的场景中发挥作用。
-
字符串编辑距离
:在自然语言处理中,用于拼写检查、文本相似度比较等。
-
硬币组合问题
:在金融、自动售货机等领域,可用于找零方案的计算。
-
用元素符号拼写单词
:在化学教育、化学研究等场景中,帮助学生和研究人员探索元素符号的组合。
-
化学元素序列游戏
:可作为化学教学中的趣味活动,帮助学生熟悉元素名称。
-
扁平化嵌套列表
:在数据处理、JSON 解析等场景中,将嵌套数据结构转换为扁平结构便于处理。
-
游程编码与解码
:在数据压缩、图像编码等领域,减少数据存储空间和传输带宽。
8. 递归编程的优势与挑战
8.1 优势
- 代码简洁 :递归可以用较少的代码实现复杂的逻辑,使代码更易理解和维护。例如,扁平化嵌套列表的递归算法,通过简单的步骤就可以处理多层嵌套的情况。
- 符合问题本质 :对于一些具有递归性质的问题,如树的遍历、分形图形的绘制等,递归方法能够自然地表达问题的解决思路。
8.2 挑战
- 性能问题 :递归调用会增加函数调用的开销,可能导致栈溢出错误。例如,在处理大规模数据时,递归计算平方根可能会消耗大量的内存和时间。
- 理解困难 :递归的执行过程相对复杂,对于初学者来说,理解递归的调用栈和返回值可能会有一定的难度。
9. 优化递归编程的建议
为了克服递归编程的挑战,可以采取以下优化建议:
-
使用尾递归
:尾递归是指递归调用是函数的最后一个操作,这样可以避免栈溢出问题。例如,在递归计算平方根时,可以将递归调用转换为尾递归形式。
-
记忆化
:对于一些重复计算的问题,可以使用记忆化技术,将已经计算过的结果保存起来,避免重复计算。例如,在计算字符串编辑距离时,可以使用字典来保存已经计算过的子问题的结果。
-
迭代替代
:对于一些简单的递归问题,可以考虑使用迭代方法来替代,以提高性能。例如,前 n 个正整数求和的问题,使用迭代方法可以避免递归调用的开销。
10. 总结与展望
通过对递归编程练习的学习,我们掌握了多种递归算法的实现方法,了解了递归编程的优势和挑战,并学会了一些优化递归编程的技巧。在未来的编程实践中,我们可以根据问题的特点选择合适的方法,充分发挥递归编程的优势,同时避免其带来的问题。
希望这些内容能够帮助你更好地理解和应用递归编程,在编程的道路上不断进步!
以下是一个简单的流程图,展示了递归编程的一般思路:
graph TD;
A[定义问题] --> B[确定基本情况];
B --> C[设计递归步骤];
C --> D[实现递归函数];
D --> E[测试和优化];
在实际应用中,我们可以按照这个流程来解决各种递归问题。首先明确问题的定义,然后找出基本情况,接着设计递归步骤,实现递归函数,最后进行测试和优化,以确保程序的正确性和性能。
超级会员免费看
1万+

被折叠的 条评论
为什么被折叠?



