题目描述:
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
本文将从以下三种方法介绍本题
- 首先,类似于合法括号,本题可以先选定一个数,对于下一个数,选择放在当前数的左边,右边或中间,生成的下一个集合继续进行下一次迭代,直到遍历完所有情况。
- 考虑到第一种方法需要进行频繁的字符串操作,所以第二种方法是先选定一个字符当前缀,然后逐步增加前缀的长度。如果前缀长度等于输入的长度,就得到了一组解。需要注意的是本方法用到递归,需要处理好平行状态。(这种方法的好处还有不需要那麽多空间来记录)
- 进一步考虑,类似于DFS,本题还可以用递归+回溯。
逐步生成法:
#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
list<string> getPermutation(string A){
list<string> res;
string st(1,A.at(0));
res.push_back(st);
int len = A.length();
for(int i = 1; i < len; i++){
list<string> res_new;
char c = A.at(i);
for(list<string>::iterator it = res.begin(); it != res.end(); it++){
string str = *it;
string s_new = *it+c;// 加在后面
res_new.push_back(s_new);
s_new = c+*it;//加在前面
res_new.push_back(s_new);
// 加在中间
for(int j = 1; j < str.length(); j++){
s_new = str.substr(0,j) + c + str.substr(j);
res_new.push_back(s_new);
}
}
res = res_new;
}
return res;
}
int main(){
string s;
cin >> s;
list<string> res = getPermutation(s);
for(list<string>::iterator it = res.begin(); it != res.end(); it++){
cout << *it << " ";
}
cout << endl;
return 0;
}
前缀法:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int k, sum = 0;
void getPermutation(string perfix, string arr){
if(perfix.length() == arr.length()){
sum++;
if(sum == k){
cout << perfix << endl;
exit(1);
}
}
for(int i = 0; i < arr.length(); i++){
char c = arr[i];
if(count(perfix.begin(),perfix.end(),c) < count(arr.begin(),arr.end(),c))
getPermutation(perfix+c,arr);
}
}
int main(){
string s;
cin >> s >> k;
getPermutation("", s);
return 0;
}
回溯法:
#include<iostream>
#include<string>
#include<list>
#include<algorithm>
using namespace std;
list<string> res;
void getPermutationCore(string arr, int k){
if(k == arr.length()){
res.push_back(arr);
}
for(int i = k; i < arr.length(); i++){
swap(arr[k], arr[i]); // 把k后面的每个字符放到k的位置上
getPermutationCore(arr, k+1); // 放好之后再放下一个元素
swap(arr[k], arr[i]); // 回溯
}
}
int main(){
string s;
cin >> s;
getPermutationCore(s,0);
res.sort();
for(list<string>::iterator it = res.begin(); it != res.end(); it++)
cout << *it << " ";
cout << endl;
return 0;
}