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