经典递归算法之排列,组合,集合和换零钱, Python yield实现.
来源:互联网 发布:gis矢量数据融合 编辑:程序博客网 时间:2024/05/22 12:01
对于每个函数名'f',还有个非递归的版本'xf',例如 perm和xperm, comb和xcomb等.
全部是以生成器的形式实现.例如:perm((1,2,3))返回(1,2,3)的全排列生成器.
def subsets(s): if not s: yield () else: head, rest = s[:1], s[1:] for se in subsets(rest): yield se yield head + sedef xsubsets(s): stk = [(s, ())] while stk: s, head = stk.pop() if not s: yield head else: stk.append((s[1:], head + s[:1])) stk.append((s[1:], head))def comb(s,k=None): n = len(s) if k is None: k = n if k < 0: raise ValueError("k must be non-negative") if k > n: return () def recur(s, k, n): if k == n: yield s elif k == 0: yield () else: head, rest = s[:1], s[1:] yield from recur(rest, k, n-1) yield from (head + x for x in recur(rest, k-1, n-1)) return recur(s, k, n)def xcomb(s,k=None): n = len(s) if k is None: k = n if k < 0: raise ValueError("k must be non-negative") if k > n: return () def recur(s, k, n): stk = [(s, k, n, ())] while stk: s, k, n, head = stk.pop() if k == n: yield head + s elif k == 0: yield head else: stk.append((s[1:], k-1, n-1, head + s[:1])) stk.append((s[1:], k, n-1, head)) return recur(s, k, n) def wperm(s): if not s: yield () else: head, rest = s[:1], s[1:] rest_n = len(rest) + 1 for ele in wperm(rest): for i in range(rest_n): yield ele[:i] + head + ele[i:]def xwperm(s): stk = [(s, ())] while stk: s, head = stk.pop() if not s: yield head else: h = s[:1] n = len(head) + 1 for i in range(n): stk.append((s[1:], head[:i] + h + head[i:]))def perm(s,k=None): for cs in comb(s,k): yield from wperm(cs)def xperm(s,k=None): for cs in xcomb(s,k): yield from xwperm(cs)def exch(my,arr): if my < 0 or not arr: pass elif not arr[1:]: c = arr[0] div, mod = divmod(my, c) if mod == 0: yield tuple(c for _ in range(div)) else: head, rest = arr[:1], arr[1:] yield from exch(my, rest) yield from (head + x for x in exch(my-arr[0], arr))def xexch(my,arr): stk = [(my, arr, ())] while stk: my, arr, head = stk.pop() if my < 0 or not arr: continue if not arr[1:]: c = arr[0] div, mod = divmod(my, c) if mod == 0: yield head + tuple(c for _ in range(div)) else: stk.append((my-arr[0], arr, head + arr[:1])) stk.append((my, arr[1:], head)) import itertoolss = tuple(range(5))arr=tuple(range(1,6000))def test(): for i in range(len(s)+1): assert(set(itertools.combinations(s,i))==set(comb(s,i)))def test2(): for i in range(len(s)+1): assert(set(itertools.permutations(s,i))==set(perm(s,i))) def test3(): for x in xexch(10,arr): print(x) #assert(set(xexch(10,arr))==set(exch(10,arr)))def test4(): for i in range(len(s)+1): assert(set(xcomb(s,i))==set(comb(s,i))) for x in xcomb(s, 2): print(x)def test5(): for ss in subsets(arr): print(ss) print('---') for ss in xsubsets(arr): print(ss) assert(set(subsets(arr))==set(xsubsets(arr)))def test6(): #assert(set(perm(arr,3))==set(xperm(arr,3))) for x in xperm(arr,3): print(x) if __name__=='__main__': test6()
0 0
- 经典递归算法之排列,组合,集合和换零钱, Python yield实现.
- 换零钱实现之贪心算法
- 排列和组合算法 C语言经典实现
- 排列和组合算法 C语言经典实现
- 递归算法之全组合排列
- 递归实现全排列和组合
- 算法之排列和组合算法
- 排列和组合的非递归算法的C语言实现
- 排列和组合的非递归算法的C语言实现
- 全排列和组合的实现算法
- 全排列和组合的实现算法
- 换零钱的算法
- 全排列算法之非递归实现
- C++ 全排列和组合算法(递归)
- C递归版的全排列和组合算法
- 递归练习之换零钱方式统计(c/c++)
- 求集合子集,和全排列的递归算法实现(c++,Dev C++调试通过)
- 排列和组合算法
- ul li 排序 移动 非常简单
- 变量的存储属性与内存管理
- ReportStudio入门教程(七十八) - JS-禁止右键单击功能
- C++异常处理示例
- Android Volley框架的几种post提交请求方式
- 经典递归算法之排列,组合,集合和换零钱, Python yield实现.
- 在linux系统上搭建QT移植mini2440步骤
- 利用施瓦茨排序获得范围数据的并集
- iOS中的生成随机数方法
- 东软学习,oracle函数与触发器2
- TabHost导致百度定位功能失效
- 企业inhouse网页发布流程
- Spring AOP原理及拦截器
- 常犯错误总结