Erlang程式设计与问题解决/排列
外观
排列,类似组合,有不可重复的排列和可重复的排列。排列是从一个列表取出指定数目的项目,对取出的相同项目来说,不同的顺序代表不同的排列。
排列函数的规格是
permutation ( N , List ) => [ permutation_1, permutation_2, ... ]
在列表 List 中,要取出 N 个,结果得到一列排列情况,每一种排列情况都包含 N 个项目。
不重复的排列
[编辑]从任何列表中取 0 个项目,结果只取得空列表。
permutation(0, _) -> [[]];
从空列表中,指定要取任何数目的项目,结果是空集合。
permutation(_, []) -> [];
接著是一般情况。要从列表取指定 N 项,做法是将每个项目轮流当做第一笔资料,每一个第一笔资料与其他 N-1 项排列情况结合。在此,列表型示 ( list comprehension ) 可以发挥功用。
permutation(N, Xs) -> [ [X|Rs] || X <- Xs, Rs <- permutation(N-1, Xs--[X]) ].
测试执行结果:
> test:permutation(3,[a,b,c,d]). [[a,b,c], [a,b,d], ...... > test:permutation(5, [a,b,c]). [] > length(test:permutation(3, lists:seq(1,8))). 336 % 從 8 個數字中取 3 個,結果有 336 種組合
可重复的排列
[编辑]可重复的排列是取出每一项之后,又对原列表取剩下的 N-1 项。将上述不重复排列的程式第三句做一点修改,就会得到重复的排列。
permutation(N, Xs) -> [ [X|Rs] || X <- Xs, Rs <- permutation(N-1, Xs) ].
测试执行结果:
> test:permutation(2,[a,b,c]). [[a,a],[a,b],[a,c],[b,a],[b,b],[b,c],[c,a],[c,b],[c,c]] > test:permutation(5, [a,b,c]). [[a,a,a,a,a], [a,a,a,a,b], ...... > length(test:permutation(3, lists:seq(1,8))). 512 % 從 8 個數字中取 3 個可重複排列,結果有 512 種組合