2022/9/11---写递归之前怎么思考?

递归三要素:
1.递归算法要由基本结束条件,即最小问题可以直接求解
2.调用自身(递归)可以求解已经缩小规模的同类问题
3.问题可以缩小规模,向最小问题靠近   (分治策略,即复杂问题分解为子问题的和)

注意点:

1.系统默认的recursionlimit限制为1000,因为系统的调用栈是有限的。如果实在需要更大的递归次数,可以使用sys模块的setrecursionlimit函数来修改。

2.尽量站在高层分析递归,不需要清楚具体实现细节

3.如何考虑递归算法?答:1)分析清楚最小问题  2)思考问题如何通过递归缩小规模

下面通过几个递归的应用进一步体会怎么用第三条注意点写递归算法

#进制转换
#算法分析
#最小问题:data
#汉诺塔问题
#最小问题:一个盘子直接移动
#可以递归减小问题规模:问题=前N-1个盘子经由目标盘移动到中间盘(递归)+第N个盘子移动到目标柱(最小问题)+前N-1个盘子移动到目标盘(递归)
def hanoi(N,start_pole,middle_pole,object_pole):
    """这个函数把N个盘子从star_pole经由middle_pole移动到object_pole"""
    if N>=1:
        hanoi(N-1,start_pole,object_pole,middle_pole)
        move(N,start_pole,object_pole)
        hanoi(N-1,middle_pole,start_pole,object_pole)
def move(plate_serial_number,start,end):
    """这个函数把一个盘子从start杆移动到end杆"""
    print('盘子[{}]从{}移动到{}'.format(plate_serial_number,start,end))
#最少硬币数问题
'''减少计算量的关键在于记住已有的结果。简单的做法是把最少硬币数的计算结果存储在一张
表中,并在计算新的最少硬币数之前,检查结果是否已在表中。如果是,就直接使用结果,而不
是重新计算'''
#最小问题(能直接解决的问题):找零=货币面值 一个硬币就可以完成最少硬币找零+找零在已知最少硬币表中,直接返回对应的值
#分治策略,缩小问题规模:
"""
以人民币为例,若找零数>1的话,问题可分解为:
1)问题=找1次1元钱+找change-1的最少找零数(递归解决缩小规模的同类问题)
2)问题=找1次5元钱+找change-5的最少找零数(递归解决缩小规模的同类问题)
3)问题=找1次10元钱+找change-10的最少找零数(递归解决缩小规模的同类问题)
4)问题=找1次20元钱+找change-20的最少找零数(递归解决缩小规模的同类问题)
5)问题=找1次50元钱+找change-50的最少找零数(递归解决缩小规模的同类问题)
6)问题=找1次100元钱+找change-100的最少找零数(递归解决缩小规模的同类问题)
"""
def mincoins(change, currency, knownlist):
    """求最少硬币数量
    参数说明:
    change=找零
    currency=货币面值列表,大小为change的全0列表
    knownlist=记录f(change)的最小值
    """
    times = change  # 开始时,硬币数设为最大
    if change in currency:
        knownlist[change] = 1  # 记录change的最少硬币数
        return 1
    elif knownlist[change] > 0:  # 说明记录有change的最少硬币数
        return knownlist[change]
    else:
        for change in [change - i for i in currency if i < change]:  # 先找的那张钱要不change小,否则change就是负数了,着显然不合理
            current_times = mincoins(change, currency, knownlist)  # 获得new_change的最少硬币数
            knownlist[change] = current_times  # 记录change-i的最少硬币数
            if times > current_times + 1:
                times = current_times + 1  # current_times是change的一种方法的最少硬币数,如果小于times就更新
    return times
mincoins(63,[1,5,10,25],[0]*64)
#递归分治策略实现二分查找:
#最小问题:f(first,last)=None 当first==last 或  f(first,last)=middle, 当lst[middle]=value 
#分治策略缩小问题规模: f(fist,last)=f(middle+1,last) 当lst[middle]value 
#f是获得(first,last)中value值索引得函数
def binary_search(lst,value):
    first=0
    last=len(lst)-1
    middle=(first+last)//2
    #最小问题1
    if first==last:
        return None
    #最小问题2
    elif lst[middle]==value:
        return middle
    #分治策略
    else:
        if lst[middle] 

你可能感兴趣的:(数据结构与算法,python)