/*
算法思路 :
aacc四个元素的全排列,我们可以划分为3个元素的全排列,
3个划分为2个,到最后只剩下1个元素,就不需要排列。
我们让每一个元素作为打头元素,交换,然后进行递归,再交换。
如果该打头元素在前面中已经有过,则忽略这种情况。
*/
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
/*
finish函数检查第i个元素是否在前面元素[k...i-1]中出现过
*/
int finish(char list[], int k, int i)
{
if(i > k)
{
for(int j=k; j<i; j++)
{
if(list[j] == list[i]) //元素重复出现,返回0
{
return 0;
}
}
}
return 1;
}
int ans = 0; //用来记录不重排列的个数
int prem(char str[], int left, int right)
{
if(left == right) //数组左右边界相等意思为数组中只剩下一个元素
{
ans++;
for(int i=0; i<=right; i++)
printf("%c",str[i]);
printf("\n");
}
/*
数组中还有多个元素待排列,递归产生排列(将元素划分成单个元素)
*/
for(int i=left; i<=right; i++)
{
if(finish(str, left, i)) //finish检查当前元素是否重复出现过
{
swap(str[left], str[i]); //swap函数用来交换元素
prem(str, left+1, right);
swap(str[left], str[i]);
}
}
}
int main()
{
int n;
printf("请输入排列元素的个数:\n");
scanf("%d",&n);
printf("请输入%d个元素:\n", n);
char str[100003];
getchar(); ///吸收输入元素个数后面换行符
for(int i=0; i<n; i++)
{
scanf("%c", &str[i]);
}
printf("所有不同排列为:\n");
/*
调用排列函数
三个参数依次为 数组名,数组左边界,数组右边界
*/
prem(str, 0, n-1);
printf("不重复的排列总数为:%d\n", ans);
return 0;
}