算法实现原理:
假如abc排列组合会得到abc,acb,bac,bca,cab,cba六种情况。
1)首先将abc的第一个字母放到三者中的第一位得到abc,接着剩下两个字母bc,可以将bc中的第一个字母放到两者中的第一位得到abc,也可以将bc中的第二个字母放到两者中的第一位得到acb。
2)将abc的第二个字母放到三者中的第一位得到bac,接着剩下两个字母ac,可以将ac中的第一个字母放到两者中的第一位得到bac,也可以将ac中的第二个字母放到两者中的第一位得到bca。
…
以此类推。
如果按以上的算法计算acc的排列组合,那么会得到acc,acc,cac,cca,cca,cac六种情况。
那么需要排除其中重复的情况。
对重复的元素序列进行排列组合:
在交换并且进行递归的时候,需要判断交换的两者之间是否有与后者相同的数。比如在计算acc的排列组合时,将acc的第三个字母放到三者中的第一位与将acc的第二个字母放到三者中的第一位是重复的情况,那么则不需要将第三个字母放到第一位进行排列。
代码实现:
#include <iostream>
using namespace std;
void perm(char*, const int, const int);
bool isHaveSame(char*, const int, const int);
int main()
{
char list[10];
cin >> list; //当输入abc时
perm(list, 0, strlen(list)-1); // strlen(list)-1==2
return 0;
}
void perm(char* x, const int start, const int end)//核心函数
{
if (start == end)//当运算到最后一位时则表示这种情况排列完成,输出其结果
{
for (int i = 0; i <= end; i++)
cout << x[i];
cout << endl;
}
else
{
for (int i = start; i <= end; i++)
{
if (isHaveSame(x,start,i))//如果start与i之间没有重复的话,进行排列
{
swap(x[start], x[i]);//先将第i位放到start位置
perm(x, start + 1, end);//将除去一位的字母串进行递归排列
swap(x[start], x[i]);//排列完再将其交换回来
}
}
}
}
bool isHaveSame(char* x, const int start, const int end)//判断在star-end之间是否有重复的元素
{
for (int i = start; i < end; i++)
{
if (x[i] == x[end])//如果有则为0
return 0;
}
return 1;//如果没有则为1
}
来源:CSDN
作者:bev.
链接:https://blog.csdn.net/Bevisss/article/details/104573138