排列组合生成算法CombinationAll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Channels;

namespace CombinationAll
{
    public class Program
    {
        private List<string> _input = new List<string>()
        {
            "a", "b", "c", "d" // ,"e","f","g","h","i",
        };


        private static void Main(string[] args)
        {
            var program = new Program();


            // NSelectOne(ref program._input).ForEach(Console.WriteLine);
            // NSelectTwo(ref program._input).ForEach(Console.WriteLine);
            // NSelectThree(ref program._input).ForEach(Console.WriteLine);
            // System.Console.WriteLine("===============================");
            // NSelectM(ref program._input, 1).ForEach(Console.WriteLine);
            // NSelectM(ref program._input, 2).ForEach(Console.WriteLine);
            // NSelectM(ref program._input, 3).ForEach(Console.WriteLine);
            // System.Console.WriteLine("===============================");


            for (var i = 0; i < program._input.Count; i++)
            {
                Console.WriteLine($"input,{program._input.Count}选{i + 1}");
                NSelectM(ref program._input, i + 1).ForEach(Console.WriteLine);
            }


            Console.WriteLine("---->over");
        }

        /// <summary>
        /// KeyMethod
        /// </summary>
        /// <param name="input">原列表</param>
        /// <param name="m">选几个</param>
        /// <returns>结果</returns>
        /// <exception cref="Exception">有bug</exception>
        private static List<string> NSelectM(ref List<string> input, int m)
        {
            if (m > input.Count)
            {
                throw new Exception("n选m,m必须小于n!");
            }

            List<string> result     = new List<string>();
            Stack<int>   indexStack = new Stack<int>();

            GoDeepFor(ref input, m, -1, ref result, ref indexStack);
            return result;


            static void GoDeepFor(ref List<string> input, in int m, in int preIndex, ref List<string> result,
                                  ref Stack<int>   indexStack)
            {
                for (int index = preIndex + 1; index < input.Count; index++)
                {
                    if (index > input.Count) break;
                    indexStack.Push(index);

                    if (indexStack.Count >= m)
                    {
                        var str = "";
                        foreach (int num in indexStack.Reverse())
                        {
                            str += input[num];
                        }

                        result.Add(str);
                        indexStack.Pop();
                    }
                    else
                    {
                        GoDeepFor(ref input, m, index, ref result, ref indexStack);
                        indexStack.Pop();
                    }
                }
            }
        }

        #region NoNeed

        private static List<string> NSelectThree(ref List<string> input)
        {
            List<string> result = new List<string>();

            for (var i = 0; i < input.Count; i++)
            {
                if (i > input.Count) break;

                for (int j = i + 1; j < input.Count; j++)
                {
                    if (j > input.Count) break;

                    for (int k = j + 1; k < input.Count; k++)
                    {
                        if (k > input.Count) break;

                        result.Add(input[i] + input[j] + input[k]);
                    }
                }
            }

            return result;
        }

        private static List<string> NSelectTwo(ref List<string> input)
        {
            List<string> result = new List<string>();

            for (var i = 0; i < input.Count; i++)
            {
                if (i > input.Count) break;

                for (int j = i + 1; j < input.Count; j++)
                {
                    if (j > input.Count) break;

                    result.Add(input[i] + input[j]);
                }
            }

            return result;
        }

        private static List<string> NSelectOne(ref List<string> input)
        {
            List<string> result = new List<string>();
            for (var i = 0; i < input.Count; i++)
            {
                if (i > input.Count) break;
                result.Add(input[i]);
            }

            return result;
        }

        #endregion
    }
}
input,4选1
a
b
c
d
input,4选2
ab
ac
ad
bc
bd
cd
input,4选3
abc
abd
acd
bcd
input,4选4
abcd
---->over

优化方向:

1. 递归缓冲;

2.C(5,2)=C(5,3);

 

 

方法+2 

 

posted @ 2020-08-29 17:09  CharyGao  阅读(248)  评论(0编辑  收藏  举报