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