排列组合之全排列
2017-03-04 15:41 牛仔裤的夏天 阅读(863) 评论(0) 编辑 收藏 举报摘要:在群里看到一个朋友发了这样一条消息:有列举组合排列的算法吗?大家讨论一下?例如有一个数组['a','b','c'],需要打印出:abc,acb, bac, bca, cab, cba。随手写了两个for循环,结果发现在5个7个或者更大的时候,结果并不对,后根据出题者给出的树的思想实现了排列,后从百度百科查到这是全排列,而网上提供了另外一种思路。这里简单总结下,并给出了一种思路的C#和js代码实现。
什么是全排列?
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
全排列的两种思路
这里以3个数字为例
1.{...} {...} 从右侧循环取字符追加到左侧,递归循环,直到右侧为空输出左侧组合值。
2.{...} {...} 从右侧循环取字符,再循环左侧每个组合,再遍历组合的每个位置插入取出的字符,递归循环,直到右侧为空输出左侧组合值列表。
第一种思路的C#和js实现
C#实现如下
class Program { static string result = ""; static void Main(string[] args) { ArrayList source = new ArrayList() { "a", "b", "c", "d", "e", "f" }; ArrayList des=new ArrayList(){}; movechar(des, source); Console.WriteLine(result + "\n"); Console.ReadKey(); } private static void movechar(ArrayList des, ArrayList source) { if (source.Count == 0) { string strdes = ""; for (int i = 0; i < des.Count; i++) strdes += des[i] + ","; result += strdes.Substring(0, strdes.Length - 1) + "|"; } for (int i = 0; i < source.Count; i++) { ArrayList newdes=new ArrayList(); ArrayList newsource=new ArrayList(); foreach (string strdes in des) newdes.Add(strdes); newdes.Add(source[i]); for(int j=0;j<source.Count;j++) { if (j != i) newsource.Add(source[j]); } movechar(newdes, newsource); } } }
JS实现如下:
var a = ['a', 'b', 'c', 'd', 'e','f']; var r = function (pre, left) { if (left.length < 1) { console.log(pre.join(',')); return; } for(var i = 0; i < left.length; i++) { var nextPre = pre.slice(); nextPre.push(left[i]); var one = left.slice(); one.splice(i, 1); r(nextPre, one); } }; r([], a);
可见js实现起来代码要简洁很多。C#在list的处理上没有提供很好的移除字符的方法。
鉴于写作能力有限,若有描述不当或明显错误的,欢迎指正!