全排列(九度OJ1120)
1.题目描述:
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有’a’ < ‘b’ < … < ‘y’ < ‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入描述:
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出描述:
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:已知S = s1s2…sk , T = t1t2…tk,则S < T 等价于,存在p (1 <= p <= k),使得s1 = t1, s2 = t2, …, sp - 1 = tp - 1, sp < tp成立。
每组样例输出结束后要再输出一个回车。
示例1
输入
复制
abc
输出
复制
abc
acb
bac
bca
cab
cba
2.基本思路
说到排列问题我的第一反应就是回溯法中的排列树问题,题目也是简单直接,但是还有一个额外的要求就是输出的字符串应该按照ASCII码的大小升序输出。因此我们需要把排列树得到的排列结果用字符串数组存储起来,然后调用sort函数进行排序,这里为了排序的方便采用了结构体来存储字符串。
为了更加直观的来了解排列树,我们来看一下输入字符串为"abc"的搜索过程。
我们将所有的叶子节点存储在结构体数组当中,然后根据字符串的大小对结构体数组进行排序。
3.代码实现
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int n;
int cnt=0;
char str[27];
struct store{
char data[27];
}buf[1001];
bool cmp(store a,store b){
return strcmp(a.data,b.data)<0;
}
void backtack(int t){
if(t==n){
printf("str=%s\n",str);
strcpy(buf[cnt++].data,str);
}
else{
for(int i=t;i<n;i++){
swap(str[t],str[i]);
backtack(t+1);
swap(str[t],str[i]);
}
}
}
int main()
{
while(~scanf("%s",str)){
cnt=0;
n = strlen(str);
backtack(0);
sort(buf,buf+cnt,cmp);
for(int i=0;i<cnt;i++){
printf("%s\n",buf[i].data);
}
printf("\n");
}
return 0;
}