permutation in c#

前端 未结 5 2136
无人共我
无人共我 2021-01-13 05:16

Is it possible to generate all permutations of a collection in c#?

char[] inputSet = { \'A\',\'B\',\'C\' };
Permutations permutations = new Permu         


        
5条回答
  •  天命终不由人
    2021-01-13 05:34

    I built these Extensions Methods for Enumerable

    The following Generics Methods can find Permutations as well as Combinations of an IEnumerable of any type. Visit http://github.com/MathewSachin/Equamatics for more

    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); }
    }
    }
    

    `

提交回复
热议问题