【题目描述】
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有‘a’ <‘b’ < … <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
【输入描述】
只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
【输出描述】
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。
【样例输入】
abc
【样例输出】
abc
acb
bac
bca
cab
cba
【分析】
(1)比较经典的搜索回溯题目,不同的是由数字改成了字符
(2)定义一个输出函数,一旦满足要求就输出
(3)输入保证由小到大
【参考代码1】
/* 字符全排列 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; char str[10],ans[10]; //用户输入的字符串,结果数组 int n; bool flag[10]; //标记数组,用来标记这个字符有没有出现过 void dfs(int step) { if(step==n) //如果步数到了n(长度),就输出ans { ans[step]='\0'; //加上结尾,防止过多输出 cout<<ans<<endl; } for(int i=0;i<n;i++) //枚举字符,从0开始 if(flag[i]==0) //如果当前的字符没有被使用过 { flag[i]=1; //把当前字符标记为使用过 ans[step]=str[i]; //把当前字符放到结果数组当中 dfs(step+1); //搜索下一个位置 flag[i]=0; //回溯一步 } } int main() { memset(flag,0,sizeof(flag)); //初始化标记数组 scanf("%s",str); //读入字符串 n=strlen(str); //测量字符串长度,用来判断是到头 dfs(0); //注意,此处是从0开始的 return 0; }
另外一个框架的版本:
【参考代码2】
#include<cstdio> #include<iostream> #include<cstring> using namespace std; char ans[10001];//存放答案的字符数组 int len; //字符数组长度 bool flag[10001]={0}; //标记这个数有没有被使用过,0表示没有使用 char s[50]; //要读入的数据 int dfs(int k) { for(int i=0;i<len;i++) //字符数组从0开始枚举 { if(flag[i]==0) //如果当前这个字符没有使用过 { flag[i]=1; //当前字符使用过就标记 ans[k]=s[i]; //把当前字符放到结果字符数组里 if(k==len-1) //到达边界就输出 { ans[len]='\0'; //在末尾加上结束标识符 cout<<ans<<endl; } else dfs(k+1); //否则,就继续枚举下一个位置 flag[i]=0; //回溯一步 } } } int main() { cin>>s; len=strlen(s); dfs(0); //从第一个位置开始 }
返回目录:题解目录