Re: [问题] 排列组合的疑问

楼主: adgjl5645 (今天不想哭)   2017-06-09 10:05:02
※ 引述《ptt0720 (湿湿)》之铭言:
: def combos(n, m = 1):
: if n < m:
: return []
: res = [[n]]
: for i in range(m, n):
: l = [i]
: for j in combos(n - i, i):
: res += [l + j]
: return res
: print (combos(5))
: 我写题目遇到一题 题目是这样
: 假如输入3 要列出所有相加等于3的情况
: [3],[2,1],[1,1,1]
第一次看到这种问题跟写法的时候心里一定会有很多问号,但是其实没有需要这么害怕,
让我们冷静下来看看这个问题
首先让我们回到题目本身,题目的意思是要我们找到所有数字合等于 n 的解,接着稍微
的看一下程式码,我们看到他在函数里面又呼叫了一次自己,这种递回的写法,递回的写
法虽然比较复杂但是逻辑是比较简单的
一般来说,用到递回的情况是在这个计算的过程中会用到相同的计算,这是什么意思呢?
举例来说,当你在做费波那契数列的时候,算 n 的值的过程就会要用到 n-1 的值
回到程式码上,首先 2 3 行是检查没有答案的情况,4 初始化了答案 n 本身一定会是一
组解,接着就是关键的双层循环
首先,最外层的循环从 1 开始到 n ,但在这边我们可能还没清楚他想做什么,于是我们
看向第二个循环,这边出现了 combos(n-i, i),我们先不管这边的语法是什么,我们先
看看 combos 这边想做的是什么,这边算的是由 i 开始总和是 n-i 的解,回传成一个 l
ist,所以第二层的 for 就是对这些解一个一个再加入 I 然后加进答案里
到这边其实整份程式的架构就差不多出来了,怎么说呢?借由程式码我们可以从新理解这
个题目是解法,所有和是 n 的解可以由所有和是 n-k 的解再加上 k ,然后遍历所有 k
, 这就是这份程式码在做的事情
: 然后爬文看到一个算式比较简单的写法
: 但是还是不太懂
: 第七行为什么可以让循环在def执行?
至于语法上重点是他要的是 combos 的回传值,而不是 function 本身
: 还有他的每一层迭代我也不是很了解
: 目前只理解到 第一次执行会留下自己的值
: 接下来把自己的值-1 (ex:3-1=2) 继续分解2
: 假如输入是5呢
: [5],[1,4],[1,1,3],[1,1,1,2],[1,1,1,1,1]
: 接下来的
: [1,2,2],[2,3]是如何进行迭代的 我就不太清楚了
: 希望板上神人们可以指导一下
希望有回答到你的问题
楼主: adgjl5645 (今天不想哭)   2017-06-09 10:08:00
补充一点 我觉得这种写法比较像是 divide and conquer把问题拆成更小的问题

Links booklink

Contact Us: admin [ a t ] ucptt.com