zoukankan      html  css  js  c++  java
  • Python笔试——递归算法学习

    一、要素

    1. 必须有最终停止发展下线的边界条件,否则将无穷循环
    2. 必须有与原始问题结构一致的,但输入规模一定小于原始问题规模的递归结构

    二、递归解决问题的步骤

    step1. 不妨设该问题有解fnc(p),其中p为函数fnc的输入

    step2. 递归

    将原始问题p分解为k个子问题,,即p1, p2, p3, ... , pk

      ——由于求解原问题的函数为fnc, 因此求解各子问题的函数依然为fnc

      ——子问题对应的输入元素个数要小于原问题的输入元素个数

    step3. 边界条件

    建立子问题的解与原问题的解的关系 

      ——根据解的关系得到递归结构

      ——子问题的最简形式存在解

     

    下面用三个例子来说明递归算法求解问题的步骤:

    例1——判断回文

    步骤

    step1. 不妨设已经有一个函数isPalindrome(s)可用来判断是否回文数,在这里我们可以设s='level'

    step2. 将isPalindrome(s)进行分解:

        isPalindrome('level') = isPalindrome('eve') and ('l' == 'l')

    step3. 边界条件

        len(s) <= 1  ——>  True

    代码实现

    def isPalindrome(s):
        if len(s)<=1:
            return True
        else:
            return isPalindrome(s[1:-1]) and s[0]==s[-1]
    
    print(isPalindrome('levl'))

    例2——全排列

    步骤

    step1. 不妨设已经有一个函数permutation(s)可用来解决该问题,假设s='ABC'

    step2. 将原问题分解为规模更小的子问题:

        字符‘A’ + permutation('BC')

        字符‘B’ + permutation('AC')

        字符‘C’ + permutation('AB')

        s[i] + permutation(s(阴影))

    step3. 边界条件

        len(s) <= 1  ——>  输出其本身

    代码实现

    def permutation(s):
        if len(s) == 1:
            return s
        else:
            res = []
            for i in range(len(s)):
                cha = s[i]
                rest = s[0:i]+s[i+1:]
                for j in permutation(rest):
                    tar = s[i]+j
                    res.append(tar)
            return res
    
    print(permutation('ABCd'))

    扩展

    值得一提的是,在Python中有一个模块可以帮助我们自动实现全排列功能——permutations

    用法如下:

    from itertools import permutations
    s = 'adc'
    print(permutations(s))
    print(list(permutations(s)))

    代码执行结果如下:

     可以看到,用permutations模块得出的全排列是元组类型

    例3——汉诺塔问题

    问题汉诺塔是一个发源于印度的益智游戏,也叫河内塔。相传它源于印度神话中的大梵天创造的三个金刚柱,一根柱子上叠着上下从小到大64个黄金圆盘。大梵天命令婆罗门将这些圆盘按从小到大的顺序移动到另一根柱子上,其中大圆盘不能放在小圆盘上面。当这64个圆盘移动完的时候,世界就将毁灭。

    步骤

    step1. 不妨设已经有一个函数hanio(num,start,end,helper)可用来解决该问题,其中num为圆盘数,start为起始圆柱,end为目标圆柱,helper为辅助圆柱

    step2. 将原问题分解为规模更小的子问题:

    step3. 边界条件

    当num == 1时,直接移动即可:moveSingleDesk(source,target)

    代码实现:

    n = 3
    source = ([3,2,1],'A')
    target = ([],'B')
    helper = ([],'C')
    def hanio(n,start,end,helper):
        if n == 1:
            moveSingleDisk(start,end)
        else:
            hanio(n-1,start,helper,end)
            moveSingleDisk(start,end)
            hanio(n-1,helper,end,start)
    
    def moveSingleDisk(start,end):
        x = start[0].pop()
        print('MOVING '+str(x)+' FROM '+start[1]+' TO '+end[1])
        end[0].append(x)
    
    
    print(hanio(n,source,target,helper))
  • 相关阅读:
    2049
    2046 ACM 数学
    1290 ACM 数学
    2017 ACM 字符串的本质
    1171 Big Event in HDU 01背包
    2045 数学:排列组合
    git命令(版本控制之道读书笔记)
    mysql:赋予用户权限、查看及修改端口号
    Linux系统的命令别名功能(转)
    回到上次目录、历史命令查找快捷方式及执行时间显示设置、查看系统版本
  • 原文地址:https://www.cnblogs.com/sunny0824/p/13472121.html
Copyright © 2011-2022 走看看