原题
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有 'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入格式
输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在 11 到 66 之间。
输出格式
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知 S = s_1s_2...s_k, T = t_1t_2...t_kS=s1s2...sk,T=t1t2...tk,则 S < TS<T 等价于,存在 p (1 \le p \le k)p(1≤p≤k),使得 s_1 = t_1, s_2 = t_2, ..., s_{p - 1} = t_{p - 1}, s_p < t_ps1=t1,s2=t2,...,sp−1=tp−1,sp<tp 成立。
样例
输入:abc
输出:
abc acb bac bca cab cba
思路
深搜,用 book [ n ] 标记一下哪个字符使用过。
吐槽:这题其实也可以运用面向结果编程的思路来写,因为字符串的长度只是6,而且都是不同的小写字母,那么也就只有一共6*5*4*3*2*1种情况,通过判断输入情况,直接输出结果。不过思路很简单,实现很复杂,需要将每种情况列出来。
吐槽的优化: 其实只要得出长度分别为 1 , 2 , 3 , 4 ,5 ,6 的字符串的全排列情况列出即可,因为排列的方式都是一样的,只是对应的位置的字母不同,所以可以运用变量来代替全排列,然后将读入的字符串的字母套入对应的位置,那么只需要编写 一共六中情况,复杂程度减少了。
代码
#include<iostream>
#include<algorithm>
#define ll long long
#include<string.h>
using namespace std;
int len;
char a[10];
char b[10];
int book[10];
void dfs(int key)
{
if(key>len)
{
for(int i=0;i<len;i++)
cout<<b[i];
cout<<endl;
return;
}
for(int i=0;i<len;i++)
{
if(book[i] ==0)
{
b[key-1]=a[i];
book[i]=1;
dfs(key+1);
book[i]=0;
}
}
return ;
}
int main()
{
scanf("%s",a);
len=strlen(a);
sort(a,a+len);
dfs(1);
return 0;
}