在做遞歸問題時,要保證對遞歸跳躍的信任,繼而對相應的問題尋找其遞歸實現
(1)組合:先從原始數組中選擇一個,再從剩下的集合中選擇m-1個;而后,再從剩下的集合中挑選m個元素。
/*組合代碼(eg:5選2)*/ int a[5]={1,2,3,4,5};//原始數組 int b[2];//挑選的結果 const int need=2;//需要選擇的個數 void combine(int start,int end,int x) { if(x==need) { //(1)打印組合的內容 for(int i=0;i<need;i++) { cout<<b[i]<<" "; } cout<<endl; //(2)對每一種組合進行排列 //permute(b,0,2);//見下 return; } if((end-start)<(need-x))//如果剩下的元素個數<需要的數 { return; } b[x]=a[start];//先選擇一個 combine(start+1,end,x+1);//再從剩下的集合中選擇m-1個 combine(start+1,end,x);//然后再從剩下的集合(即縮小的集合中選擇m個) }
(2)排列:為了列出一個長度為n的字符串的所有排列,可以一次挑選n個字母中的一個;然后在后面列出其余的n-1個字母可能的排列組合。
/*排列函數*/ /*參數:c 為 int 型數組的地址 start 為排列數組的起始下標 end 為排列數組的結束下標+1 */ void permute(int c[],int start,int end) { if(start==end) //挑選完畢 { /*打印數組*/ for(int i=0;i<end;i++) { cout<<c[i]<<" "; } cout<<endl; } else { for(int i=start;i<end;i++) { swap(c[i],c[start]);//一次挑選n個字母中的一個 permute(c,start+1,end);//再對其余的n-1個字母一次挑選 swap(c[i],c[start]);//恢復原字符串 } } }
問題牽引:在對字符數組進行排序的時候,應當注意傳入參數的方式,即 char str[] 和 char * str的區別
(1)char * str 的str,指向一塊內存區域,可以隨時改變;但其指向的內容不可以修改
(2)char str[] 其地址不可改變,即常量指針;但數組內容可以改變