zoukankan      html  css  js  c++  java
  • 排列与组合

    全排列

    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}种排列方式。");
            }
        }
    }
    

    组合

    方法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}种组合方式。");
            }
        }
    }
    

    方法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}种组合方式。");
            }
        }
    }
  • 相关阅读:
    LeetCode Merge Two Sorted Lists 归并排序
    LeetCode Add Binary 两个二进制数相加
    LeetCode Climbing Stairs 爬楼梯
    034 Search for a Range 搜索范围
    033 Search in Rotated Sorted Array 搜索旋转排序数组
    032 Longest Valid Parentheses 最长有效括号
    031 Next Permutation 下一个排列
    030 Substring with Concatenation of All Words 与所有单词相关联的字串
    029 Divide Two Integers 两数相除
    028 Implement strStr() 实现 strStr()
  • 原文地址:https://www.cnblogs.com/wj033/p/9125484.html
Copyright © 2011-2022 走看看