亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++中求組合數的各種方法總結詳解

2020-01-26 16:17:35
字體:
來源:轉載
供稿:網友

【問題】      組合問題

問題描述:找出從自然數1、2、... 、n中任取r個數的所有組合。例如n=5,r=3的所有組合為:

1,2,3
1,2,4
1,3,4
2,3,4
1,2,5
1,3,5
2,3,5
1,4,5
2,4,5
3,4,5

用程序實現有幾種方法:

1)窮舉法

程序如下
【程序】
#include<stdio.h>
const int n=5,r=3;
int    i,j,k,counts=0;

int main()
{
     for(i=1;i<=r ;i++)
        for(j=i+1;j<=r+1;j++)
            for( k=j+1;k<=r+2;k++){
               counts++;
               printf("%4d%4d%4d/n",i,j,k);
           }
printf("%d",counts);
return 0;
}
但是這個程序都有一個問題,當r變化時,循環重數改變,這就影響了這一問題的解,即沒有一般性。


2)遞歸法
分析所列的10個組合,可以采用這樣的遞歸思想來考慮求組合函數的算法。
設函數為void    comb(int m,int k)為找出從自然數1、2、... 、m中任取k個數的所有組
合。當組合的第一個數字選定時,其后的數字是從余下的m-1個數中取k-1數的組合。這
就將求m個數中取k個數的組合問題轉化成求m-1個數中取k-1個數的組合問題。設函數引
入工作數組a[ ]存放求出的組合的數字,約定函數將確定的k個數字組合的第一個數字放
在a[k]中,當一個組合求出后,才將a[ ]中的一個組合輸出。第一個數可以是m、m-1、
...、k,函數將確定組合的第一個數字放入數組后,有兩種可能的選擇,因還未去頂組
合的其余元素,繼續遞歸去確定;或因已確定了組合的全部元素,輸出這個組合。細節
見以下程序中的函數comb。
【程序】
#include <time.h>
#include <iostream>

using namespace std;

# define      MAXN      100
int a[MAXN];
int counts=0;

void printtime(void) //打印當前時間的函數
{
      char tmpbuf[128];
      time_t ltime;
      struct tm *today;

      time(<ime);
      today = localtime(<ime );
      strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S",today);
      cout<<tmpbuf<<endl;
}


void      comb(int m,int k)
{     int i,j;
      for (i=m;i>=k;i--)
      {     a[k]=i;
          if (k>1)
              comb(i-1,k-1);
          else
          {  
              counts++;
              /*
              for (j=a[0];j>0;j--)
                  printf("%4d",a[j]);
              printf("/n");
              */
          }
      }
}

int main()
{  

      int m,r;
      cout<<"m"<<endl;
      cin>>m;
      cout<<"r"<<endl;
      cin>>r;
      counts=0;
      a[0]=r;
      printtime();
      comb(m,r);
      cout<<counts<<endl;
      printtime();
      return 0;
}

 


這是我在網上找到的程序,稍微修改了一下。程序寫的很簡潔,也具有通用性,解決了問題。

3)回溯法

采用回溯法找問題的解,將找到的組合以從小到大順序存于a[0],a[1],…,a[r-1]
中,組合的元素滿足以下性質:

(1)     a[i+1]>a[i],后一個數字比前一個大;
(2)     a[i]-i<=n-r+1。
按回溯法的思想,找解過程可以敘述如下:
      首先放棄組合數個數為r的條件,候選組合從只有一個數字1開始。因該候選
解滿足除問題規模之外的全部條件,擴大其規模,并使其滿足上述條件(1),候選組合
改為1,2。繼續這一過程,得到候選組合1,2,3。該候選解滿足包括問題規模在內的全
部條件,因而是一個解。在該解的基礎上,選下一個候選解,因a[2]上的3調整為4,以
及以后調整為5都滿足問題的全部要求,得到解1,2,4和1,2,5。由于對5不能再作調
整,就要從a[2]回溯到a[1],這時,a[1]=2,可以調整為3,并向前試探,得到解1,3,
4。重復上述向前試探和向后回溯,直至要從a[0]再回溯時,說明已經找完問題的全部
解。

在網上我始終沒有找到可以正常執行的完整程序,所以我只好花了一天的時間來自己來寫這個程序,并且改變輸出從0開始而不是從1開始,這樣做的目的是 為了擴展程序的用途,適應c/c++語言的需要,這樣輸出就可以當作要選擇的組合數組的地址序列,可以對長度為n任意類型數組找出r個組合。我對它進行了 優化,如果你認為還有可以優化的地方,請不惜賜教,。^_^

#include <time.h>
#include <iostream>
#include <iomanip>
using namespace std;

# define      MAXN      100
int a[MAXN]; //定位數組,用于指示選取元素集合數組的位置,選取元素集合數組0 起始
void comb(int m,int r)
{  
      int cur;//指示定位數組中哪個成員正在移進

      unsigned int count=0;

      //初始化定位數組,0 起始的位置 ,開始的選擇必是位置 0,1,2
      for(int i=0;i<r;i++)
          a[i]=i;

      cur=r-1;//當前是最后一個成員要移進

       do{
          if (a[cur]-cur<=m-r ){ 

              count++;
              /*
              for (int j=0;j<r;j++)
                  cout<<setw(4)<<a[j];
              cout<<endl;
              */
              a[cur]++;

              continue;
          }
          else{
              if (cur==0){
                  cout<<count<<endl;
                  break;
              }

              a[--cur]++;
              for(int i=1;i<r-cur;i++){
                  a[cur+i]=a[cur]+i;
              }

              if(a[cur]-cur<m-r)
                  cur=r-1;               
          }
      }while (1);
}

 

 

void printtime(void) //打印當前時間的函數
{
      char tmpbuf[128];
      time_t ltime;
      struct tm *today;

      time(<ime);
      today = localtime(<ime );
      strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S",today);
      cout<<tmpbuf<<endl;
}

int main (int argc, char *argv[])
{

      int m,r;
      cout<<"m"<<endl;
      cin>>m;
      cout<<"r"<<endl;
      cin>>r;
      printtime();
      comb(m,r);   
      printtime();
      return(0);
}

同上面的遞歸的程序進行比較,同樣用g++ o2優化。當n=40,r=11,屏蔽掉輸出,得到的結果都是2311801440項,遞歸程序用了23至24秒,回溯用了19至20秒。


4)利用數組

  定義:從n個數中取出m個數的組合。
  實現機理:先創建一個字符串數組,其下標表示 1 到 n 個數,數組元素的值為1表示其下標代表的數被選中,為0則沒選中。    
    然后初始化,將數組前 m 個元素置 1,表示第一個組合為前 m 個數。    
    然后從左到右掃描數組元素值的 10 組合,找到第一個 "10" 后交換 1 和 0 的位置,變為 01,而后將該10組合前的1和0重新組合(1放在前邊,其個數為10組合前1的個數,0放在后邊,其個數為10前0的個數,而后接10的倒轉組合 01)。當m 個 1 全部移動到最右端時,就得到了最后一個組合。    
    例如求 5 中選 3 的組合:    
    1     1     1     0     0     //1,2,3    
    1     1     0     1     0     //1,2,4    
    1     0     1     1     0     //1,3,4    
    0     1     1     1     0     //2,3,4    
    1     1     0     0     1     //1,2,5    
    1     0     1     0     1     //1,3,5    
    0     1     1     0     1     //2,3,5    
    1     0     0     1     1     //1,4,5    
    0     1     0     1     1     //2,4,5    
    0     0     1     1     1     //3,4,5  

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品成人国产乱一区| 97久久精品国产| 欧美激情性做爰免费视频| 中日韩美女免费视频网站在线观看| 久久久久久有精品国产| 成人免费视频在线观看超级碰| 国产91在线播放| 超碰精品一区二区三区乱码| 91精品国产91久久久久久不卡| 成人a视频在线观看| 欧美电影免费观看电视剧大全| 777精品视频| 国产婷婷97碰碰久久人人蜜臀| 日韩欧美成人免费视频| **欧美日韩vr在线| 中文字幕成人精品久久不卡| 久久最新资源网| 国产成人精品999| 亚洲欧美视频在线| 亚洲人午夜精品免费| 91精品国产91| 欧美三级免费观看| 国产精品久久精品| 欧美大码xxxx| 欧美福利视频在线| 国内精品免费午夜毛片| 精品久久中文字幕久久av| 欧美电影院免费观看| 91精品在线观看视频| 九九精品视频在线观看| 福利精品视频在线| 国产情人节一区| 国内精品模特av私拍在线观看| 亚洲九九九在线观看| 欧美激情一区二区三区在线视频观看| 成人网在线免费看| 福利视频导航一区| 亚洲国产91精品在线观看| 中文字幕亚洲欧美在线| 成人高清视频观看www| 亚洲成人精品久久| 日本成人在线视频网址| 亚洲激情在线观看视频免费| 日韩精品视频三区| 欧美大尺度在线观看| 91免费人成网站在线观看18| 午夜精品久久久久久久99热浪潮| 欧美成人精品一区| 亚洲成人激情在线观看| 亚洲综合日韩在线| 亚洲精品aⅴ中文字幕乱码| 欧美日韩中文字幕综合视频| 亚洲深夜福利视频| 国色天香2019中文字幕在线观看| 精品在线观看国产| 欧美黑人性生活视频| 少妇高潮 亚洲精品| 欧美精品成人91久久久久久久| 91久久久在线| 国产日韩欧美91| 久久久伊人欧美| 国产伦精品一区二区三区精品视频| 福利精品视频在线| 精品少妇一区二区30p| 国产一区二区三区在线观看视频| 久久99久久99精品中文字幕| 亚洲第一精品夜夜躁人人躁| 这里只有精品视频在线| 亚洲视频在线观看网站| 亚洲天堂网站在线观看视频| 亚洲精品99久久久久中文字幕| 色狠狠久久aa北条麻妃| 亚洲免费视频在线观看| 日韩av资源在线播放| 国产精品国产自产拍高清av水多| 国产精品久久久久久搜索| 国产成人精品日本亚洲专区61| 亚洲日本中文字幕| 97久久精品国产| 午夜精品国产精品大乳美女| 国产日韩欧美在线| 欧美性猛交xxxx久久久| 色偷偷噜噜噜亚洲男人| 最近2019中文字幕第三页视频| 亚洲一区二区中文| 成人黄在线观看| 欧美精品在线网站| 日韩精品极品视频免费观看| 国产日韩精品一区二区| 91精品中文在线| 亚洲免费中文字幕| 欧美成人一区在线| 欧美成人精品一区二区三区| 91在线国产电影| 欧美中文在线观看| 欧美性猛交xxxxx水多| 久久视频中文字幕| 亚洲国产欧美在线成人app| 日韩电影免费在线观看中文字幕| 欧美成人免费在线观看| 国内久久久精品| 国产精品久久久久国产a级| 欧美在线性爱视频| 国产精品久久久久久久久久| 精品视频中文字幕| 伊人久久免费视频| 国产精品久久久久久久久久久久久久| 欧美美女15p| 亚洲字幕在线观看| 成人精品久久av网站| 日本一区二三区好的精华液| 久久久久久国产免费| 欧美成人精品不卡视频在线观看| 久久九九热免费视频| 精品综合久久久久久97| 国产精品成人av性教育| 国产视频亚洲视频| 国产成人精品免费久久久久| 日韩一区二区三区在线播放| 亚洲欧美激情一区| 亚洲最大成人在线| 国产精品久久久久av免费| 青青草成人在线| 18久久久久久| 国产精品成人v| 国产一区二区三区直播精品电影| 日韩一区二区福利| 97视频在线免费观看| 久久精品视频中文字幕| 欧美激情一级欧美精品| 97婷婷大伊香蕉精品视频| 亚洲午夜av久久乱码| 久久久久久久国产精品视频| 午夜精品久久久久久久99热浪潮| 国产日韩欧美日韩大片| 日韩在线中文字幕| 久久资源免费视频| 91久久久久久久久| 8090成年在线看片午夜| 亚洲国产精品推荐| 伊人久久精品视频| 性亚洲最疯狂xxxx高清| 亚洲欧美变态国产另类| 久久久久日韩精品久久久男男| 国产精品免费观看在线| 欧美寡妇偷汉性猛交| 中日韩美女免费视频网址在线观看| 国产精品成久久久久三级| 成人在线激情视频| 91视频免费在线| 9.1国产丝袜在线观看| 久久91精品国产91久久跳| 日韩精品在线观看网站| 正在播放欧美视频| 理论片在线不卡免费观看| 欧美三级欧美成人高清www| 国产精品久久久久久久久免费| 欧美成人黑人xx视频免费观看| 成人亲热视频网站| 国产在线观看一区二区三区| 国产精品va在线播放我和闺蜜| 91免费精品视频| 国产成人中文字幕| 欧美一级淫片丝袜脚交|