全排列问题也是一个比较常见的问题,解决的算法大多使用递归,分治策略,递归搭配回溯算法等等。
本节介绍的是使用其中之一,运用递归和分治策略进行书写。
很多人都发现为什么要在头文件加入<set>文件呢 因为我想做的是把用户输入的不符合常规的,eg:122
3个元素,理应是3!也就是6组全排列,但是由于有两个2,其实只有3组,所以呢我想把重复的忽略掉。我第一个想到的就是集合了。
算法思想也就是 每次将当前元素与后面的元素进行一次交换,可以生成新的排列,每个元素第一次交换都是和自己,然后和后面的元素进行交换。
交换另写了一个函数swap(char,char) 递归函数是permutation。
输入形式以字符串输入,无空格间隔,如果想采用有空格间隔的,读者可以自行完成。
最后进行输出集合的时候也是采用了两种遍历,哪一种都可以完成功能,读者记住一个即可。
#include <iostream>
#include <string>
#include<set>
using namespace std;
set<string> str;
void swap(char& a, char& b)
{
char c = b;
b = a;
a = c;
}
void permutation(string s, int cur)
{
if (cur == s.length())
{
string st="";
for (int i = 0; i < s.length(); i++)
st=st+s[i]+" ";
str.insert(st);
}
else
for (int i = cur; i < s.length(); i++)
if (s[i] != s[cur] || i == cur)
{
swap(s[i], s[cur]);
permutation(s, cur + 1);
swap(s[i], s[cur]);
}
}
int main()
{
string s;
cin >> s;
permutation(s, 0);
for (set<string>::iterator it = str.begin(); it != str.end(); it++)
cout << *it << endl;
//for (string ss : str)
// cout << ss << endl;
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/cf836da724e44f92b99cccd53fada962.png)
![](https://i-blog.csdnimg.cn/blog_migrate/77b2e87628938829540155d2b97bc960.png)