题目
给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有‘a’ <‘b’ < ... <‘y’<‘z’,而且给定的字符串中的字母已经按照从小到大的顺序排列。
输入说明
只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。
输出说明
输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。
输入样例
abc
输出样例
abc
acb
bac
bca
cab
cba
解题思路
采用递归法,n为字符串长度,每次递归将位置x的字母依次和位置x+1,x+2……n-1的字母调换顺序(swap函数),完成一次调换后,将调换后的字符串传入下一层x+1的递归,实际上进行了像蓝线那样的分割,将蓝线后面的那个字符(位置x)依次和后面的字符调序,最后x递归到n-1层级,进行输出。这里注意,需要将每次递归第一次调序的字符串(橙色字符串)进行暂存,并在最后一次调序后已经传入下次递归的字符串修改为暂存的字符串,这个字符串就会返回至上层递归,以便上层递归正确进行每次调序,这一步很重要,很多的解题方法直接粗暴的把调序完的字符串传入下层递归后就再次调序(即恢复原来的顺序),这样做会导致上一层递归调序混乱,使得输出的字符串并不是字母序比较小的排列在前面。(如图二对比)
解题代码
#include<stdio.h>//顺序输出全排列
#include<string.h>
#include<stdlib.h>
void swap(char* a, char* b);
void creat(int x, int n, char* p);
void copy(char* a, char* b, int size);
int main()
{
char* p;
p = (char*)malloc(10000);
scanf("%s", p);
printf("\n");
creat(0, strlen(p), p);
return 0;
}
void creat(int x, int n, char* p)
{
int i; char* temp; temp = (char*)malloc(10000);
if (x == n-1)
{
for (i = 0;i < n;i++)
printf("%c", *(p + i));
printf("\n");
}
else
{
for (i = x; i < n; i++)
{
if (i == x)
{
copy(temp, p, n);
}
swap(p + i, p + x);
creat(x + 1, n, p);
if (i == n-1)
{
copy(p, temp, n);
}
}
}
}
void swap(char* a, char* b)//交换
{
char temp;
temp = *a;
*a = *b;
*b = temp;
}
void copy(char* a, char* b, int size)//拷贝字符串b到a
{
int i;
for (i = 0; i < size; i++)
{
*(a + i) = *(b + i);
}
}