Python3的简单递归问题

Python3的简单递归问题

一些简单递归问题的思路

看了林信良老师的书重新写了这些东西,说起来python完成这些东西相当有趣呢

1.hanoi(汉诺塔问题)

汉诺塔问题应该是递归的入门问题,很多人(我和我的小伙伴)都是从汉诺塔问题开始学习递归的思路。(多年前在课堂苦苦思索汉诺塔的日子,是我逝去的青春——sad)

def movit(num,X,Y,Z):
    if num == 1:
        print(X,'->',Z)
    else:
        movit(num-1,X,Z,Y)
        print(X,'->',Z)#movit(1,X,Y,Z),有些人是这么用的
        movit(num-1,Y,X,Z)

movit(3,'x','y','z')#测试用例

对于每一个碟片,我们只需要移动它到目标点就好了。

多层次的移动可以看作是三个部分:

  • 移动在起点的上部分(n-1个)碟片到暂存点,其中可能有多个,所以我们将其描述为X通过Z移动到Y。(X->Z->Y)
  • 移动最下面的碟片到目标点位,即为(X->Z),因为只有一片,直接移动过去就好了。
  • 将刚刚第一步中,移动到Y的那部分移动到目标点,,即为(Y->X->Z)
    每一个多层次都可以看作是多个单个碟片的移动,相当有趣。

2.八皇后问题

八皇后问题也十分有趣,但是究其思路其实非常简单,当你做出他的时候,可能会疑惑为什么自己花了相当长时间在这个问题上面。

def isSafe(q,qs):
    return all(not checkSame(q,q1) for q1 in qs)

def checkSame(q1,q2):
    return (q1[0] == q2[0] or # 同行
            q1[1] == q2[1] or # 同列
            abs(q1[0] - q2[0]) == abs(q1[1] - q2[1])) # 对角线

def printQueens(qs):
    chess = [
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0]
    ]
    for q in qs:
        chess[q[0]-1][q[1]-1] = 1
    for row in chess:
        for pt in row:
            print(' Q' if pt else ' .',end = '' )
        print()



def putall(n):
    def put(k):
        return [[]] if k == 0  else [[(k,col)] + lastReturns
                                     for lastReturns in put(k-1)
                                     for col in range(1,n+1)
                                     if isSafe((k,col),lastReturns)]
    return put(n)


for qs in putall(8):
    printQueens(qs)
    print()

我们知道饭要一口一口吃,棋子也是一颗一颗放。
整个八皇后问题其实只是简单的遍历的操作,但在python的实现上就变得相当的有趣了。
下面是注意事项(readme):

  1. 从下往上,让八个皇后乖乖站好只需要叫他们出来,然后再打出在屏幕上就好了,qs是每八个皇后。
  2. 再实现产生 qs 的方法putall(),该函数需要产生一个八列的二维数组,每一个一维数组存放qs
  • 完成每一次合理的八皇后,都需要一个一个的放棋子。
  • 对于第n个下的棋子,需要对前面n-1个棋子比较位置,是否可以下这个位置,若不是,那么不下。
  • 下第一个棋子,不需要对前面棋子比较。

3.骑士周游问题

骑士周游问题在我看来比上述问题稍微麻烦一点(我才不是懒得写代码了)
我们将其当作是下64个骑士棋子(其实没啥区别),这样更容易理解我的思路:
第一个棋子用户输入,没啥好说的。
对于第n个棋子,他都有八个方向可以走,而下一个棋子同样是。

  • 每一次下棋事件,如果找不到可以下的位置,则break
  • 如果只有一个可以下的位置,那么直接下。

先下难下的位置,然后再下容易下的位置,这是一个数学问题,而我(也不知道为什么)讨厌解释数学问题

  • 如果有多个可以下的位置,那么探索所有可以下的点,将当前点存放在写的栈中,然后找到所有可以下的点的所有路径数。loop

代码?什么代码?我为什么要写这玩意?马上吃饭了

4.思考

递归:

  • 描述第一个点
  • 再描述第n个点
发布了3 篇原创文章 · 获赞 3 · 访问量 85

猜你喜欢

转载自blog.csdn.net/qq_39715162/article/details/104716683
今日推荐