排列与组合

526823-20180602152337448-250448016.png

全排列

class Program
{
    private static void Perm(int[] data, int k, ref int count)
    {
        int size = data.Length;
        if (k == size - 1)
        {
            count++;
            Console.WriteLine(string.Join(',', data));
        }
        else
        {
            for (int i = k; i < size; ++i)
            {
                if (i != k)
                    Swap(ref data[i], ref data[k]);

                Perm(data, k + 1, ref count);

                if (i != k)
                    Swap(ref data[i], ref data[k]);
            }
        }
    }

    private static void Swap(ref int a, ref int b)
    {
        b = Interlocked.Exchange(ref a, b);
    }

    static void Main(string[] args)
    {
        int n;
        string nStr;
        while (true)
        {
            while (true)
            {
                Console.WriteLine("输入一个正整数:");
                nStr = Console.ReadLine();
                if (int.TryParse(nStr, out n))
                {
                    break;
                }
            }

            var data = Enumerable.Range(1, n).ToArray();
            int count = 0;
            Perm(data, 0, ref count);
            Console.WriteLine($"总计{count}种排列方式。");
        }
    }
}

526823-20180602150730646-1379702107.png

组合

526823-20180602175903547-259282029.png

方法1: n个元素里取m个, 相当于先选中一个,然后从剩下的n-1个元素中取m-1个

class Program
{
    public static void Combine(int[] data, int k, int m, int[] indexArr, ref int count)
    {
        int n = data.Length;
        for (int i = (k == m ? n - 1 : indexArr[k] - 1); i >= 0; i--)
        {
            indexArr[k - 1] = i;

            if (k > 1)
            {
                Combine(data, k - 1, m, indexArr, ref count);
            }
            else
            {
                count++;
                Console.WriteLine(string.Join(",", indexArr.Select(c => data[c])));
            }
        }
    }

    static void Main(string[] args)
    {
        int n = 0, m = 0;
        string nStr, mStr;
        while (true)
        {
            while (true)
            {
                Console.WriteLine("输入n:");
                nStr = Console.ReadLine();
                Console.WriteLine("输入m:");
                mStr = Console.ReadLine();

                if (int.TryParse(nStr, out n) && int.TryParse(mStr, out m) && m > 0 && n >= m)
                {
                    break;
                }
            }

            var data = Enumerable.Range(1, n).ToArray();
            int count = 0;
            var indexArr = new int[m];
            Combine(data, m, m, indexArr, ref count);
            Console.WriteLine($"从{n}个元素中取{m}个元素,总计{count}种组合方式。");
        }
    }
}

526823-20180602175317829-1854151519.png

方法2:选择第一个,选择第二个,直到选够m个

class Program
{
    public static void Combine2(int[] data, int k, int m, List<int> indexList, ref int count)
    {
        int selected = indexList.Count;
        int n = data.Length;

        if (selected == m)
        {
            count++;
            Console.WriteLine(string.Join(",", indexList.Select(c => data[c])));
        }
        else
        {
            //选一个, 剩余的元素需要足够选出m个。
            for (int i = k; i < n - m + selected + 1; i++)
            {
                indexList.Add(i);

                Combine2(data, i + 1, m, indexList, ref count);

                indexList.RemoveAt(indexList.Count - 1);
            }
        }
    }

    static void Main(string[] args)
    {
        int n = 0, m = 0;
        string nStr, mStr;
        while (true)
        {
            while (true)
            {
                Console.WriteLine("输入n:");
                nStr = Console.ReadLine();
                Console.WriteLine("输入m:");
                mStr = Console.ReadLine();

                if (int.TryParse(nStr, out n) && int.TryParse(mStr, out m) && m > 0 && n >= m)
                {
                    break;
                }
            }

            var data = new int[n];
            for (int i = 0; i < n; i++)
            {
                data[i] = i + 1;
            }
            int count = 0;
            var outList = new List<int>();
            Combine2(data, 0, m, outList, ref count);
            Console.WriteLine($"从{n}个元素中取{m}个元素,总计{count}种组合方式。");
        }
    }
}

转载于:https://www.cnblogs.com/wj033/p/9125484.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值