题目描述
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有'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成立。
例子输入
abc
例子输出
abc acb bac bca cab cba
分析
假设字符串中的元素个数为n。通过读题,我们可以发现,题目要求字母序比较小的排列在前面,因此,对于每种排列的第一个字母,其顺序为a,b,c......那么,我们不妨先把排列中的第一个字母定下来,然后我们需要做的事情就是对剩余的n-1个元素进行全排列了。以此类推,我们可以把n一直减小到1,那么事情就变得比较简单了。落实到实际的操作中,我们所作的就是按照从前往后的顺序把给定字符串中的某一个元素挑出来,放入一个新的字符串中,然后对剩余的字符串重复上面的操作,直到字符串中仅剩1个元素,这时便可以将新的字符串输出。
代码不难给出:
#include<iostream>
#include<string.h>
using namespace std;
char c[10]{};//这个数组是用来输入的
char c1[10]{};//这个数组是用来输出的
int place = 0;//用来记录c1中目前有多少个元素
void all_rank(char c[10]) {//全排列函数
if (strlen(c) == 1) {//当c中仅剩一个元素时,就可以输出c1了
c1[place] = c[0];
cout << c1 << endl;
}
else {
int i, j, k;
char a[10]{};//这个数组是用来表示挑出某个元素后c中剩下的元素的
for (i = 0; i < strlen(c); i++) {//从前往后按顺序挑出元素
c1[place] = c[i];
place++;
for (j = 0, k = 0; j < strlen(c); j++, k++) {
if (j == i) {
k--;
}
else {
a[k] = c[j];
}
}//上面的循环用来给a赋值,不改变元素间的相对位置
all_rank(a);//对剩余元素组成的字符串,即a,进行全排列
place--;
}
}
}
int main() {
cin >> c;
all_rank(c);
return 0;
}