这里主要介绍字符串排列组合问题,高中数学常见的题目,不用详细介绍,看例子就可以解决问题
"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); } } }