全排列
#region /// <summary> /// 全排列 递归 考虑重复 /// Peter /// </summary> public static String[] Permutation(String s) { if (s.Length == 1) { String[] res = new String[1]; res[0] = s; return res; } else { StringBuilder sbuilder = new StringBuilder(); Char[] cs = s.ToCharArray(); Array.Sort(cs); s = new String(cs); Char pre = '0'; for (Int32 i = 0; i < s.Length; i++) { if (i == 0) { pre = s[i]; sbuilder.Append(String.Join(",", Merge(s[i], Permutation(s.Substring(0, i) + s.Substring(i + 1)))) + ","); } else { if (s[i] == pre) { continue; } else { sbuilder.Append(String.Join(",", Merge(s[i], Permutation(s.Substring(0, i) + s.Substring(i + 1)))) + ","); pre = s[i]; } } } return sbuilder.ToString().Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries); } } public static String[] Merge(Char c, String[] s) { for (Int32 i = 0; i < s.Length; i++) { s[i] = c + s[i]; } return s; } #endregion #region /// <summary> /// 全排列 非递归 没有重复元素! /// Peter /// 给定已知序列 P = A1A2A3An ( Ai!=Aj , (1<=i<=n , 1<=j<=n, i != j ) ) /// 方法为: /// 1.从低位到高位(从后向前),找出“不符合趋势”的数字。即找到一个Pi,使P(i) < P(i+1)。 /// 若找不到这样的pi,说明我们已经找到最后一个全排列,可以返回了。 /// 2.在 P(i+1)P(i+2)Pn 中,找到一个P(j),便得 P(j)"刚刚好大于"P(i). /// ("刚刚好大于"的意思是:在 P(i+1)P(i+2)Pn 中所有大于P(i)的元素构成的集合中最小的元素.) /// 3.交换 P(i) , P(j) 的位置.注意:此处不改变i和j的值,改变的是P(i)和P(j). /// 4.交换后, P(1)P(2)P(3)P(n) 并不是准确的后一个排列。因为根据第1步的查找,我们有P(i+1) > P(i+2) > . > Pn /// 即使进行了Pi和Pj的交换,这仍然是这一部分最大的一个排列。将此排列逆序倒置(变成最小的排列)即为所求的下一个排列. /// 5.重复步骤1-4,直到步骤1中找不到“不符合趋势”的数字. /// </summary> public static List<String> Permutation1(String s) { Char[] cs = s.ToCharArray(); Array.Sort(cs); s = new String(cs); List<String> list = new List<String>(); list.Add(s); while (true) { s = FindNext(s); if (s == null) break; list.Add(s); } return list; } public static String FindNext(String cur) { Int32 p1, p2; for (Int32 i = cur.Length - 1; i > 0; i--) { if (cur[i - 1] < cur[i]) { p1 = i - 1; char min = cur[i]; p2 = i; for (Int32 j = i; j < cur.Length; j++) { if (cur[j] > cur[p1]) { if (cur[j] < min) { min = cur[j]; p2 = j; } } } Char[] cs = cur.ToCharArray(); char temp = cs[p1]; cs[p1] = cs[p2]; cs[p2] = temp; Array.Reverse(cs, p1 + 1, cs.Length - p1 - 1); return new String(cs); } } return null; } #endregion static void Main(string[] args) { Program p = new Program(); String str = "abcc"; Int32 start = Environment.TickCount; String[] res = Program.Permutation(str); Console.WriteLine("time :" + (Environment.TickCount - start)); Console.WriteLine(res.Length); foreach (String s in res) Console.WriteLine(s); Console.WriteLine("--------------"); start = Environment.TickCount; List<String> res2 = Program.Permutation1(str); Console.WriteLine("time :" + (Environment.TickCount - start)); Console.WriteLine(res2.Count); foreach (String s in res2) Console.WriteLine(s); }
作者:Peter
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.