1.组合问题
问题描述:从n个元素中选出k个元素,列出所有可能的情况
template<typename T>
void combineCore(vector<T> data, int n, int k, int start, vector<T> & v, vector<vector<T>> & res)
{
if (k < 0) return;
else if (k == 0)
res.push_back(v);
else {
for (int i = start; i < n; i++) {
v.push_back(data[i]);
combineCore(data, n, k-1, i+1, v, res);
v.pop_back();
}
}
}
template<typename T>
vector<vector<T>> combine(vector<T> data, int n, int k)
{
vector<vector<T>> res;
vector<T> v;
combineCore(data, n, k, 0, v, res);
return res;
}
2.全排列
(1) 问题描述:求n个元素的所有可能的组合
template <typename T>
void PermutationCore(vector<T> & v, int start, vector<vector<T>> & res)
{
if (start == v.size()) {
res.push_back(v);
return;
}
else {
for (int i = start; i < v.size(); i++) {
if (v[i] != v[start])
swap(v[i], v[start]);
PermutationCore(v, start+1, res);
if (v[i] != v[start])
swap(v[i], v[start]);
}
}
}
template <typename T>
vector<vector<T>> Permutation(vector<T> v)
{
vector<vector<T>> res;
PermutationCore(v, 0, res);
return res;
}
(2) 问题描述:从n个元素选出k个元素,求这k个元素的全排列
template <typename T>
void PermutationCore(vector<T> & v, int k, int start, vector<vector<T>> & res)
{
if (start == k) {
vector<T> temp(v.begin(), v.begin()+k);
res.push_back(temp);
return;
}
else {
for (int i = start; i < v.size(); i++) {
if (v[i] != v[start])
swap(v[i], v[start]);
PermutationCore(v, k, start+1, res);
if (v[i] != v[start])
swap(v[i], v[start]);
}
}
}
template <typename T>
vector<vector<T>> Permutation(vector<T> v, int k)
{
vector<vector<T>> res;
PermutationCore(v, k, 0, res);
return res;
}
注意:(1),(2)没有考虑到元素中有重复元素出现的情况,因此返回值当中可能有重复的组合
(3) 使用next_permutation()算法
next_permutation()算法将区间内容转换为下一种排列方式,头文件为<algorithm>
template <class BidirectionalIterator>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last);
template <class BidirectionalIterator, class Compare>
bool next_permutation (BidirectionalIterator first,
BidirectionalIterator last, Compare comp);
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(void)
{
string str = "abcd";
cout << str << endl;
while (next_permutation(str.begin(), str.end()))
cout << str << endl;
return 0;
}