排列、组合问题(递归)
生活随笔
收集整理的這篇文章主要介紹了
排列、组合问题(递归)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這里主要介紹字符串排列組合問題,高中數學常見的題目,不用詳細介紹,看例子就可以解決問題
"1212" ?
全排列結果為?1212,1221,1122,2112,2121,2211
組合結果是 ? 1,2,12
我所理解的排列組合結果是 ?1,2,12,21
解決方案:主要是利用遞歸思想
排列問題:求n個字符排列問題簡化求n-1個字符排列問題,逐層遞歸到1個字符。有n個字符的序列第一個字符與后面每一個前面沒有重復的字符交換,避免了重復序列,然后求n-1個字符全排列 ? f(char *s, int index,int len)index為第一個下標,len是s總長度
組合問題:先按照遞增排序,然后挑出無重復的元素存于另一個字符串,依次從字符串挑選1..n個字符,遞歸選擇字符串 ?combine(char *s, char *re,int len, int num)??
全排列代碼:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #define swap(a,b,c) (c)=(a),(a)=(b),(b)=(c)void permutation(char s[], int b, int len)// 長度為len的字符串,從s[i]開始全排列 {char c;if(b==len)//等價于 if(s[b]=='\0') printf("%s\n",s);if(b<len) for(int i=b; i<len; i++){int f=0;for(int j=i-1;j>=b; j--)//遍歷查詢前面有沒有出現該字符 if(s[j]==s[i]) {f=1;break;} if( f==1 ) continue;//跳過 swap (*(s+b),*(s+i),c );//交換 permutation(s,b+1,len); //從s[b+1]開始全排列 swap(*(s+b),*(s+i),c); //返回原來字符串順序 }return; } int main() {char s[]="1212";int len=strlen(s);permutation(s,0,len);system("pause");return 0; }組合代碼:
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<string> #include<iostream> using namespace std; #define swap(a,b,c) (c)=(a),(a)=(b),(b)=(c)void combine(char *s, char *re,int len, int num) //len長度的字符串s 選取num個字符自由組合存放到字符串re {if(num==0)//判斷是否完成任務,不再需要選取字符 {printf("%s\n",re);return;}if(len>=num){ combine(s,re,len-1,num);//不選取s[len-1] re[num-1]=s[len-1]; //選取s[len-1] combine(s,re,len-1,num-1); } return; } int cmp (const void *a, const void *b) {return *(char *)a-*(char *)b;} int main() {int len,i,j,k;char s[100],d[100],re[100];while(scanf("%s",s)!=EOF){len=strlen(s);qsort(s,len,sizeof(char),cmp);//s字符串遞增排序 d[0]=s[0];for(i=1,j=1; i<len; i++)//挑選出s中獨一無二的字符 存到d if(s[i]!=s[i-1])d[j++]=s[i]; d[j]='\0'; for(i=1;i<=j;i++){ re[i]='\0',combine(d,re,j,i);}}}
轉載于:https://www.cnblogs.com/GarySE/p/3263514.html
總結
以上是生活随笔為你收集整理的排列、组合问题(递归)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 栈的链式存储及其基本运算
- 下一篇: MVC中不能使用原生态的#include