【Educoder离散数学实训】计算机问题求解之递归 ※

【Educoder离散数学实训】计算机问题求解之递归 ※

关于递归,其实简单讲就是自己调用自己。往细了说,分为递归和回溯两个部分。只不过这个实训没真正意义上用到回溯而已。

T1 基于递推公式的递归

老规矩,稍微聊两句。这种基于递推公式、动态规划等方式的递归都是树形结构,其本质都是遍历,没必要递归的。之后有几个题我没写递归,直接循环就行。

#第一题
def power(a, n):
    #**********  Begin  **********#
    if n == 0 :
        return 1
    elif n == 1 :
        return a
    else :
        return a * power(a, n - 1)
    #**********  End  **********#print('*' * 20)

    for n in range(11):
        print(fib2(n))

T2 无递推公式的递归

这个题给我们一种思路,递归其实就是数学归纳。
本质上讲,递归就是从终点开始考虑问题。

#第一题
def isPal(s):
    # 请在下面编写代码
    n = len(s)
    if n == 0 or n == 1 :
        return True
    else :
        if s[0] == s[-1] :
            return isPal(s[1 : n - 1])
        else :for n in range(6):
        print(vonNeumann(n))
        
    ALPHABET = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for n in range(1,5):
        print('*' * 20)
        string = ALPHABET[:n]
        print(perm(string))

T3 递归与数学归纳法

注意前两个排序需要直接修改序列,我第二种排序更改了主函数的输出方式。

from random import *

#第一题
def findNomap(A, f):
    for a in A:
        mapped = False
        for m in f:
            if m[1] == a:
                mapped = True
                break
        if mapped == False:
            return a
    return None

def mapping(A, f):
    # 请在下面编写代码
    #**********  Begin  **********#
    n = len(A)
    if n == 1 :
        return A
    else :
        mdl = findNomap(A, f)
        if mdl :
            A.remove(mdl)
            for x in f :
                if x[0] == mdl or x[1] == mdl :
                    f.remove(x)
            return mapping(A, f)
        else :
            return A
    #**********  End  **********#
    # 请不要修改下面的代码


#第二题
def InsertSort(seq, i):
    # 请在下面编写代码
    #**********  Begin  **********#
    if i == 0 :
        return
    else :
        i = i + 1
        mdl = seq[:i - 1]
        InsertSort(mdl, i - 2)
        for j in range(i - 1) :
            if mdl[j] > seq[i - 1] :
                for k in range(j) :
                    seq[k] = mdl[k]
                seq[j] = seq[i - 1]
                for k in range(j, i - 1) :
                    seq[k + 1] = mdl[k]
                return
        for j in range(i - 1) :
            seq[j] = mdl[j]
    #**********  End  **********#
    # 请不要修改下面的代码


#第三题
def SelectSort(seq, i):
    # 请在下面编写代码
    #**********  Begin  **********#
    if i == 0 :
        return seq
    else :
        # print(seq, i)
        i = i + 1
        mx, Id = seq[0], 0
        for j in range(1, i) :
            if seq[j] > mx :
                mx, Id = seq[j], j
        return SelectSort(seq[:Id] + seq[Id + 1:], i - 2) + [mx]
    #**********  End  **********#
   
    #请不要修改下面的代码


#第四题
def QuickSort(seq):
    #请在下面编写代码
    #**********  Begin  **********#
    n = len(seq)
    if n == 1 :
        return seq
    elif n == 0 :
        return seq
    else :
        L1, L2 = [], []
        for i in range(1, n) :
            if seq[i] < seq[0] :
                L1.append(seq[i])
            else :
                L2.append(seq[i])
        return QuickSort(L1) + [seq[0]] + QuickSort(L2)
    #**********  End  **********#
    #请不要修改下面的代码


if __name__=="__main__":
    f = [(1, 3), (2, 1), (3, 1), (4, 5), (5, 5), (6, 4), (7, 6)]
    g = [(1, 3), (3, 1), (4, 5), (6, 4), (5, 7), (7, 6)]
    h = [(1, 3), (3, 2), (4, 4), (6, 7), (2, 2), (7, 5)]
    for l in [f, g, h]:
        A = [1, 2, 3, 4, 5, 6, 7]
        print(mapping(A, l))

    print('*' * 20)

    seed(999)
    test = [[],[],[],[]]
    for i in range(4):
        for j in range(10):
            test[i].append(randint(1,100))

    for l in test:
        InsertSort(l, len(l)-1)
        print(l)

    print('*' * 20)

    seed(9999)
    test1 = [[], [], [], []]
    for i in range(4):
        for j in range(10):
            test1[i].append(randint(100, 1000))

    for l in test1:
        print(SelectSort(l, len(l) - 1))

    print('*' * 20)
    seed(99999)
    test2 = [[], [], [], []]
    for i in range(4):
        for j in range(10):
            test2[i].append(randint(10, 1000))

    for l in test2:
        print(QuickSort(l))


T4 递归与动态编程

确实没有啥递归的必要,有两个题直接循环就完事儿了。
至于那个 m e m o memo memo,意义在于有些位置会被递归多次。例如说一个位置 c o s t i , j cost_{i,j} costi,j,只要有 x ≥ i x\ge i xi y ≥ j y\ge j yj,那么 ( i , j ) (i,j) (i,j)这个位置就会被递归一次。非常的耗时间而且没意义。那么我们用一个 m e m o r y memory memory数组,如果这个位置被递归过就存下来即可。

from random import *
from time import clock
#**********  Begin  **********#
#第一题
def minPathCost(cost, i, j):
    # 请在下面编写代码
    #**********  Begin  **********#
    # if i == 0 and j == 0 :
    #     return cost[0][0]
    # Min = 10**10
    # if i > 0 :
    #     Min = min(Min, minPathCost(cost, i - 1, j))
    # if j > 0 :
    #     Min = min(Min, minPathCost(cost, i, j - 1))
    # Min += cost[i][j]
    # return Min
    f= []
    for x in range(i + 1) :
        mdl = [0] * (j + 1)
        f.append(mdl)
    for x in range(i + 1) :
        for y in range(j + 1) :
            if x == 0 and y == 0 :
                f[x][y] = cost[x][y]
                continue
            f[x][y] = 10 ** 10
            if x > 0 :
                f[x][y] = min(f[x][y], f[x - 1][y])
            if y > 0 :
                f[x][y] = min(f[x][y], f[x][y - 1])
            f[x][y] += cost[x][y]
    return f[i][j]
    #**********  End  **********#
    # 请不要修改下面的代码


#第二题
def minPathCost_Memo(cost, i, j, memo):
    # 请在下面编写代码
    #**********  Begin  **********#
    if memo[i][j] :
        return memo[i][j]
    if i == 0 and j == 0 :
        memo[i][j] = cost[i][j]
        return cost[0][0]
    Min = 10**10
    if i > 0 :
        Min = min(Min, minPathCost(cost, i - 1, j))
    if j > 0 :
        Min = min(Min, minPathCost(cost, i, j - 1))
    Min += cost[i][j]
    memo[i][j] = Min
    return Min
    #**********  End  **********#
    # 请不要修改下面的代码

#第三题
def countWays(n):
    # 请在下面编写代码
    #**********  Begin  **********#
    if n == 1 :
        return 1
    elif n == 2 :
        return 2
    else :
        return countWays(n - 1) + countWays(n - 2)
    #**********  End  **********#
    # 请不要修改下面的代码

#第四题
def countWays_Memo(n, memo={
    
    }):
    # 请在下面编写代码
    f = [0] * (n + 2)
    f[1], f[2] = 1, 2
    for i in range(3, n + 1) :
        f[i] = f[i - 1] + f[i - 2]
    return f[n]
    #**********  End  **********#
    # 请不要修改下面的代码
#**********  end  **********#

if __name__=="__main__":
    randseeds = [9, 99, 999, 9999, 99999]
    for trial in range(5):
        seed(randseeds[trial])
        cost = []
        for i in range(10):
            temp = []
            for j in range(10):
                temp.append(randint(1,10))
            cost.append(temp)

        #start = clock()
        print(minPathCost(cost, 9, 9))
        #print(clock() - start)

    print('*' * 20)

    randseeds = [9, 99, 999, 9999, 99999]
    for trial in range(5):
        seed(randseeds[trial])
        cost = []
        for i in range(100):
            temp = []
            for j in range(100):
                temp.append(randint(1, 10))
            cost.append(temp)

        memo = []
        for i in range(100):
            memo.append([0] * 100)
        #start = clock()
        print(minPathCost_Memo(cost, 99, 99, memo))
        #print(clock()-start)

    print('*' * 20)

    for n in range(25,35):
        print(countWays(n))
    print('*' * 20)

    for n in range(90,100):
        print(countWays_Memo(n))





猜你喜欢

转载自blog.csdn.net/JZYshuraK/article/details/126721087