Lab-3-P1-递归

第一关:欧几里得算法

任务描述

本关任务:python实现欧几里德辗转相除法。

编程要求

参考上述实验指导编写python程序,实现输入任意正整数M和N,使用欧几里德算法正确计算二者的最大公约数。

测试说明

平台会对你编写的代码进行测试:

测试输入: 2 4 预期输出: 2和4的最大公约数为2。

测试输入: 999 991 预期输出: 999与991互质。

# #输入M和N
M = int(input())
N = int(input())
# ##请继续你的代码:
i = None
if M >= N:
    for i in range(N, 0, -1): # 这里是从大到小来获取i的值
        if N % i == 0 and M % i == 0 and i != 1: # 判断公约数
            print(f"{M}和{N}的最大公约数为{i}。")
            break
        elif i == 1:
            print(f"{M}与{N}互质。")
elif M < N:
    for i in range(M, 0, -1):
        if N % i == 0 and M % i == 0 and i != 1:
            print(f"{M}和{N}的最大公约数为{i}。")
            break
        elif i == 1:
            print(f"{M}与{N}互质。")

第二关:斐波那契数列

编程要求

补充示例代码中的fab函数,计算斐波那契数列第n项的值。

测试说明

平台会对你编写的代码进行测试:

测试输入: 请输入需要计算fabonacci数列的第几个元素:5 预期输出: 5

def fab(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fab(n - 1) + fab(n - 2)
    # 这里采用了递归的思想,要求能看出规律:从第三项起,每一项都是前两项之和


# 如果了解这个函数的通项公式的话也可以写:
"""
    m = int(((1 + 5 ** 0.5) / 2 - (1 - 5 ** 0.5) / 2) ** n / 5 ** 0.5)
    return m
"""
# ####请在此处填写代码


if (__name__ == "__main__"):
    global result
    n_str = input('请输入需要计算fabonacci数列的第几个元素:')
    n = int(n_str)
    result = fab(n)
    print(result)

第三关:汉诺塔

任务描述

本关任务:编写python程序实现汉诺塔问题的递归算法。

编程要求

  • 汉诺塔函数

Lab-3-P1-递归_第1张图片

函数释义: Hanoi()函数具有四个参数,分别为n – 圆盘个数,A、B、C 依次为从左到右三个柱子,注意,这里的A、B、C均为变量,它们真正的值取决于调用Hanoi()函数时传入的值。譬如,当我们给三个柱子取名字分别为”one”、”two”、”three”,那么调用函数之后,A的值为”one”,依次类推。用if-else结构实现汉诺塔问题的递归公式。当只有一个盘子时(if n == 1:),直接将该盘子从A移动到C即可,函数表示为输出count: A ---> C;如果有多于一个盘子,先将除最下面的盘子以外的n – 1个盘子从A移动到B,即调用Hanoi()函数,这时参数顺序为n-1,A,B,C,意思是把n-1个盘子借助柱子C从A移动到B上。第二步(即else程序块的第二行)所执行的操作为把最下面的一个圆盘从A(借助B)移动到C,因此参数顺序为1,A,C,B。第三步(即else程序块的第三行)是将除最下面的盘子以外的n – 1个盘子从B(现在已经在B上面了)移动到C,即调用Hanoi()函数,这时参数顺序为n-1,B,C,A,意思是把n-1个盘子借助柱子A从B移动到C上。

  • 主函数

参考斐波那契主函数的写法自己补充,注意count变量的赋初值问题。

测试说明

测试输入: 请输入A柱子上的圆盘个数: 3

预期输出:

  1. 1: A ---> C
  2. 2: A ---> B
  3. 3: C ---> B
  4. 4: A ---> C
  5. 5: B ---> A
  6. 6: B ---> C
  7. 7: A ---> C
def Hanoi(n, A, C, B):  # 这里的ABC不是字母而是变量名,会随着递归而改变
    # #汉诺塔递归函数主体
    # #从任务指导参考代码中抄写
    global count  # 定义了count为全局变量,防止后续中出现"count未定义",count就是执行程序的步数
    if n < 1:  # 写一个特例,防止题目中出现塔数小于1的情况
        print("invalid input")
    elif n == 1:
        print(f"{count}:\t{A} ---> {C}")
        count += 1
    else:
        Hanoi(n - 1, A, B, C)  # 返回上一步,并且将B和C的位置互换
        Hanoi(1, A, C, B)  # 执行上个语句后,直接执行elif的结果
        Hanoi(n - 1, B, C, A)  # 返回上一步,并且将A和B的位置互换


"""
(1)把n-1个盘子由A 移到 B;
(2)把第n个盘子由 A移到 C;
(3)把n-1个盘子由B 移到 C;
"""
# #汉诺塔递归函数主体
# #从任务指导参考代码中抄写

if __name__ == "__main__":
    # #自己写
    n = int(input("请输入A柱子上的圆盘个数:"))
    count = 1
    Hanoi(n, "A", "C", "B")

# 具体的思路可以参考这个【汉诺塔小游戏和递归思想-哔哩哔哩】 https://b23.tv/sUrAe71

 第四关:合并有序列表

任务描述

利用递归思想解决如下问题:编写merge(L1, L2)函数:输入参数是两个从小到大排好序的整数列表L1和L2,返回合成后的从小到大的大列表。 例如:merge([1,4,5], [3,7])会返回[1,3,4,5,7];merge([],[2,3,4])会返回[2,3,4]. 要求:

  1. 一定要用递归方式(自身调用);
  2. 只能用列表里的append()和len()函数,不能使用其他列表自带函数。

编程要求

输入两个降序整数列表,输出二者合并之后的降序列表,并对你写的每一行代码进行注释。

测试说明

测试输入: 请输入列表X:5,4,3,2 请输入列表Y:8,7,6,1 预期输出: [8, 7, 6, 5, 4, 3, 2, 1]

# # Merge两个升序列表
def merge(L1, L2):
    if len(L1) == 0: # 讨论特殊情况:L1和L2有一个是空列表时
        return L2
    elif len(L2) == 0:
        return L1
    m = []
    while len(L1) != 0 and len(L2) != 0:
        if L1[0] > L2[0]:
            m.append(L1[0])
            L1.pop(0) # 将L1的第一个数据剔除
            if len(L1) == 0:
                m.extend(L2)
        else:
            m.append(L2[0])
            L2.pop(0) # 将L2的第一个数据剔除
            if len(L2) == 0:
                m.extend(L1)
    return m


# 请完成merge函数主体

if __name__ == "__main__":
    X = [int(i) for i in input("请输入列表X:").split(",")] # 保证输入的是整数类型
    Y = [int(i) for i in input("请输入列表Y:").split(",")] # 同上
    # #请完成主函数实现X与Y的合并
    m = merge(X, Y) # 接收函数的返回值
    print(m)

你可能感兴趣的:(生鸡蛋23大计の题,数据结构,算法,python)