c#中的排列

是否可以在c#中生成集合的所有排列?

char[] inputSet = { 'A','B','C' }; Permutations permutations = new Permutations(inputSet); foreach (IList p in permutations) { Console.WriteLine(String.Format("{{{0} {1} {2}}}", p[0], p[1], p[2])); } 

我已经遇到了问题,我写了这些简单的方法:

  public static IList GeneratePermutations(T[] objs, long? limit) { var result = new List(); long n = Factorial(objs.Length); n = (!limit.HasValue || limit.Value > n) ? n : (limit.Value); for (long k = 0; k < n; k++) { T[] kperm = GenerateKthPermutation(k, objs); result.Add(kperm); } return result; } public static T[] GenerateKthPermutation(long k, T[] objs) { T[] permutedObjs = new T[objs.Length]; for (int i = 0; i < objs.Length; i++) { permutedObjs[i] = objs[i]; } for (int j = 2; j < objs.Length + 1; j++) { k = k / (j - 1); // integer division cuts off the remainder long i1 = (k % j); long i2 = j - 1; if (i1 != i2) { T tmpObj1 = permutedObjs[i1]; T tmpObj2 = permutedObjs[i2]; permutedObjs[i1] = tmpObj2; permutedObjs[i2] = tmpObj1; } } return permutedObjs; } public static long Factorial(int n) { if (n < 0) { throw new Exception("Unaccepted input for factorial"); } //error result - undefined if (n > 256) { throw new Exception("Input too big for factorial"); } //error result - input is too big if (n == 0) { return 1; } // Calculate the factorial iteratively rather than recursively: long tempResult = 1; for (int i = 1; i <= n; i++) { tempResult *= i; } return tempResult; } 

用法:

 var perms = Utilities.GeneratePermutations(new char[]{'A','B','C'}, null); 

内置任何东西。

我在这里和这里找到了几个代码项目文章,可能会帮助你实现自己的类。

  public static void Recursion(char[] charList, int loBound, int upBound ) { for (int i = loBound; i <= upBound; i++) { swap(ref charList[loBound], ref charList[i]); if (loBound == upBound) { Console.Write(charList); Console.WriteLine(""); } Recursion(charList, loBound + 1, upBound); swap(ref charList[loBound], ref charList[i]); } } public static void swap(ref char a, ref char b) { if (a == b) return; a ^= b; b ^= a; a ^= b; } public static void Main(string[] args) { string c = "123"; char[] c2 = c.ToCharArray(); Recursion(c2, 0, c2.Length-1); Console.ReadKey(); } 

我为Enumerable构建了这些扩展方法

以下generics方法可以找到排列以及任何类型的IEnumerable的组合。 访问http://github.com/MathewSachin/Equamatics了解更多信息

 using System; using System.Collections.Generic; using System.Linq; namespace Equamatics { public static class Combinatorics { #region Permute public static IEnumerable> Permute(this IEnumerable Input, int r = -1) { int n = Input.Count(); if (r == -1) foreach (var item in new Permutor(Input).Recursion(0)) yield return item; if (r > n) throw new ArgumentOutOfRangeException("r cannot be greater than no of elements"); foreach (var list in Input.Combinations(r)) foreach (var item in new Permutor(list).Recursion(0)) yield return item; } class Permutor { int ElementLevel = -1; int[] PermutationValue; T[] Elements; public Permutor(IEnumerable Input) { Elements = Input.ToArray(); PermutationValue = new int[Input.Count()]; } public IEnumerable> Recursion(int k) { ElementLevel++; PermutationValue[k] = ElementLevel; if (ElementLevel == Elements.Length) { List t = new List(); foreach (int i in PermutationValue) t.Add(Elements[i - 1]); yield return t; } else for (int i = 0; i < Elements.Length; i++) if (PermutationValue[i] == 0) foreach (IEnumerable e in Recursion(i)) yield return e; ElementLevel--; PermutationValue[k] = 0; } } public static double P(int n, int r) { if (r < 0 | n < 0 | n < r) return Double.NaN; else if (r == 0) return 1; else if (n == r) return Factorial(n); else { double Product = 1; for (int i = n - r + 1; i <= n; ++i) Product *= i; return Product; } } #endregion #region Combinations public static IEnumerable> Combinations(this IEnumerable Input, int r = -1) { if (r == -1) { yield return Input; yield break; } int n = Input.Count(); if (r > n) throw new ArgumentOutOfRangeException("r cannot be greater than no of elements"); int[] Indices = Enumerable.Range(0, r).ToArray(); yield return Indices.Select(k => Input.ElementAt(k)); while (true) { int i; for (i = r - 1; i >= 0; --i) if (Indices[i] != i + n - r) break; if (i < 0) break; Indices[i] += 1; for (int j = i + 1; j < r; ++j) Indices[j] = Indices[j - 1] + 1; yield return Indices.Select(k => Input.ElementAt(k)); } } public static double C(int n, int r) { if (r < 0 | n < 0 | n < r) return Double.NaN; else if (n - r == 1 | r == 1) return n; else if (n == r | r == 0) return 1; else if (n - r > r) return (P(n, n - r) / Factorial(n - r)); else return (P(n, r) / Factorial(r)); } #endregion public static double Factorial(int n) { if (n < 0) return Double.NaN; else if (n == 0) return 1; else { double Product = 1; for (int i = 1; i <= n; ++i) Product *= i; return Product; } } public static int Derangement(int n) { double x = 0; for (int i = 2; i <= n; ++i) { if (i % 2 == 0) x += (1 / Factorial(i)); else x -= (1 / Factorial(i)); } return (int)(Factorial(n) * x); } public static int Catalan(int n) { return (int)C(2 * n, n) / (n + 1); } } } 

`

使用递归的简单实现

  static void Main(string[] args) { char[] inputSet = { 'A', 'B', 'C' }; var permutations = GetPermutations(new string(inputSet)); foreach (var p in permutations) { Console.WriteLine(String.Format("{{{0} {1} {2}}}", p[0], p[1], p[2])); } } public static List GetPermutations(string str) { List result = new List(); if (str == null) return null; if (str.Length == 0) { result.Add(""); return result; } char c = str.ElementAt(0); var perms = GetPermutations(str.Substring(1)); foreach (var word in perms) { for (int i = 0; i <= word.Length; i++) { result.Add(word.Substring(0, i) + c + word.Substring(i)); } } return result; }