参考:Python 实现递归算法 - 另一个自己 - CSDN博客
用递归实现以下算法:
- Factorial
- Hannoi Tower
- Fibonacci
- 迷宫
使用递归计算组合(permutation)
- 对于一个元素的集合,直接返回值即可
- 对于多个元素的集合
- 遍历所有元素
- 对于任意一个元素与其他元素合并
代码如下:
利用 set 可以进行简单的 + - 操作
返回结果为 迭代器,也是可以遍历的
def naive_recursive_permute(S): if len(S) <= 1: yield list(S) else: for x in S: for P in naive_recursive_permute(S - {x}): yield [x] + P list(naive_recursive_permute({0})) list(naive_recursive_permute({0, 1})) list(naive_recursive_permute({0, 1, 2})) list(naive_recursive_permute({0, 1, 2, 3}))
output:
[[0]] Out[2]: [[0, 1], [1, 0]] Out[2]: [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]] Out[2]: [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], [1, 2, 3, 0], [1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], [2, 1, 0, 3], [2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], [3, 0, 2, 1], [3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]]
可以填写选择几个数字的排列
函数名字是组合
def combination(m_list, nb): if nb == 1: for m in m_list: yield [m] else: for k in range(len(m_list)): for i in combination(m_list[0:k]+m_list[k+1:], nb-1): yield [m_list[k]] + i list(combination([1, 2, 3, 4], 1)) list(combination([1, 2, 3, 4], 2)) list(combination([1, 2, 3, 4], 3)) list(combination([1, 2, 3, 4], 4))
output:
[[1], [2], [3], [4]] Out[52]: [[1, 2], [1, 3], [1, 4], [2, 1], [2, 3], [2, 4], [3, 1], [3, 2], [3, 4], [4, 1], [4, 2], [4, 3]] Out[52]: [[1, 2, 3], [1, 2, 4], [1, 3, 2], [1, 3, 4], [1, 4, 2], [1, 4, 3], [2, 1, 3], [2, 1, 4], [2, 3, 1], [2, 3, 4], [2, 4, 1], [2, 4, 3], [3, 1, 2], [3, 1, 4], [3, 2, 1], [3, 2, 4], [3, 4, 1], [3, 4, 2], [4, 1, 2], [4, 1, 3], [4, 2, 1], [4, 2, 3], [4, 3, 1], [4, 3, 2]] Out[52]: [[1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2], [2, 1, 3, 4], [2, 1, 4, 3], [2, 3, 1, 4], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1], [3, 1, 2, 4], [3, 1, 4, 2], [3, 2, 1, 4], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1], [4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]]
组合实现(对于 [a, a, b, c] 这种情况,可以事先处理为 [a1, a2, b, c] 进行操作,操作后在将 a1/a2 转化为 a)
def combination(m_list, nb): if nb == 1: for m in m_list: yield tuple([m]) else: for k in range(len(m_list)): for i in combination(m_list[0:k]+m_list[k+1:], nb-1): yield tuple(sorted([m_list[k]] + list(i))) set(list(combination([1, 2, 3, 4], 1))) set(list(combination([1, 2, 3, 4], 2))) set(list(combination([1, 2, 3, 4], 3))) set(list(combination([1, 2, 3, 4], 4)))
output:
{(1,), (2,), (3,), (4,)} Out[67]: {(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)} Out[67]: {(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)} Out[67]: {(1, 2, 3, 4)}
迷宫(所有路径)
从某一点为起点,到达终点,利用 DFS 方法
伪代码如下:
# 首先需要定义四个方向的步长 # four directions # up, right, down, left item = [(-1, 0), (0, 1), (1, 0), (0, -1)] def find_a_way(point_start, point_end): # 将点进栈并赋值为 False ,防止后面回来 stack.push(point_start) grid[point_start] = False # 接下来根据两种情况进行判断 if point_start == point_end: # 这就是终点了,需要输出路径,并统计数目 stack.output() count += 1 else: # 按照四个方向遍历 for i in range(len(item)): point_tmp = (point_start[0]+item[i][0], point_start[1]+item[i][1]) # 如果这个点是 True,就继续往下走 if grid[point_tmp] == True: find_a_way(point_tmp, point_end) # 将进栈的数据再吐出来,并重新复制为 True stack.pop() grid[point_start] = True
首先判断上,如果可以,就卡开 find_a_way(point_tmp, point_end) 的位置,继续运行代码,然后看下一个点
如果碰巧上不可以,再看看右,如果右可以,继续卡在下一个 find_a_way(point_tmp, point_end) 的位置,此时每个点都会进栈并且标记为 False
...
以此类推,最终到达终点了,这时候进栈的数据可以打印出来了,然后运行 stack.pop() 和 grid[point_start] = True,把终点吐出来,并标记为 True
然后是返回来到 上一个 find_a_way(point_tmp, point_end) 的位置,然后继续运行下一个可行的方向,所有方向运行完以后,继续运行 stack.pop() 和 grid[point_start] = True,把这个点吐出来,并标记为 True
返回到上一点的下一个方向的时候,他又把上面的过程走了一遍。。。真的好复杂,有点乱了。。。
...
以此类推,最终退回到第一个点的 find_a_way(point_tmp, point_end) 的位置,继续运行 stack.pop() 和 grid[point_start] = True,把这个点吐出来,并标记为 True
一个路径执行完毕