现在的位置: 首页 > 综合 > 正文

组合算法(三种实现方式)

2012年08月22日 ⁄ 综合 ⁄ 共 3631字 ⁄ 字号 评论关闭

命题:从N个不同元素中取K个元素形成的组合:

        /// <summary>
        /// 递归法
        /// </summary>
        /// <param name="n">N个不同元素</param>
        /// <param name="k">取K个组合</param>
        /// <param name="initN">开始N</param>
        /// <param name="initK">开始K</param>
        /// <param name="a">参数数组</param>
        private void CombNK(int n, int k,int initN,int initK,int[] a)
        {
           
            int i, j;
            for (i = n; i >= k; i--)
            {
                a[k] = i;
                if (k > 1)
                {
                    CombNK(i - 1, k - 1,initN,initK,a);
                }
                else
                {
                    string s = "";
                    for (j = 1; j <= initK; j++)
                    {
                        s += a[j] + " ";
                    }
                    theCount++;
                    this.richTextBox1.AppendText(s + "\r\n");
                }
            }
        }
        /// <summary>
        /// 循环加1法
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        private void ComboNKEx(int n, int k)
        {
            List<int> theRets = new List<int>();
            string s = "";
            //第1个组合是123...K
            for (var b = 1; b <= k; b++)
            {
                theRets.Add(b);
                s += b + " ";
            }
            this.richTextBox1.AppendText(s + "\r\n");
            while(theRets[0]<=(n-k+1))
            {
                theRets[k-1]++;
               
                for (var j = k; j > 1; j--)
                {
                    theCount++;
                    if (theRets[j-1] > n - (k-j))
                    {
                       
                        theRets[j - 2]++;
                        theRets[j - 1] = theRets[j - 2];
                        theCount++;
                    }
                }
                OutPut(theRets, n, k);
               
            }
        }
        private void OutPut(List<int> a,int n,int k)
        {
            bool ok = true;
            int tmp = a[0];
            string s = a[0].ToString();
            for (int i = 2; i <= k;i++)
            {
                if (a[i - 1] <= tmp || a[i - 1]>n)
                {
                    ok = false;
                    break;
                }
                s += " " + a[i-1].ToString();
                tmp = a[i-1];
            }
            if (ok)
            {
                this.richTextBox1.AppendText(s + "\r\n");
                //theCount++;
            }
           
        }
        /// <summary>
        /// 回溯法
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        private void ComboNK1(int n, int k)
        {
            int i, j;
            int[] a = new int[k];
            a[0] = 1;
            i = 0;
            while (1 == 1)
            {
               
                //如果a[i]满足,则继续,如果不满足,则回溯
                if (a[i] - i <= n - k + 1)
                {
                    if (i == k - 1)
                    {
                        string s = "";
                        for (j = 1; j <= k; j++)
                        {
                            s += a[j - 1] + " ";
                        }
                        this.richTextBox1.AppendText(s + "\r\n");
                        theCount++;
                    }
                    else
                    {
                        //试探
                        i++;
                        if (i - 1 >= 0)
                        {
                            a[i] = a[i - 1];
                        }
                       
                    }
                    a[i]++;
                }
                else
                {
                    if (i == 0)
                    {
                        break;
                    }
                    //回溯
                    i--;
                    a[i]++;
                    //a[i + 1] = a[i]+1;
                   
                }
               
            }
        }

=============================

平时弄弄这些算法,主要的目的是活动一下脑子,防止痴呆....

抱歉!评论已关闭.