题目:有N个数组,每次从每个数组中取出一个数字,将他们的全排列输出出来。请输出所有的可能。例:三个数组{1,2,3} {4} {5,6},则他们的所有可能为:145的全排列,245的全排列,345的全排列,146的全排列,246的全排列,346的全排列。即:
145,154,415,451,514,541,245,254,452,425,524,542,345,354,435,453,534,543,146,164,416,461,614,641,246,264,42,6,462,624,642,346,364,436,463,634,643。
这个题,难点在于他是两个题的结合。一个问题是全排列,一个问题是N个数组的遍历规则。所以,解决的方法就是在N个数组的遍历之后,添加上全排列函数。N个数组的遍历,在于模拟他们的遍历方式,如果N是给定的数字,比如3,那么可以使用三层for循环进行这种遍历规则。但是N没有给定,所以采用递归方式来模拟这N层for循环,最后加上全排列。
代码:
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
void show(vector<vector<int>> &ve, vector<int> &flag, int k);
void parti(vector<int> &ve, int begin, int end)
{
if (begin == end)
{
for (int i = 0; i < end; ++i)
cout << ve[i];
cout << endl;
}
else
{
for (int i = begin; i < end; ++i)
{
int tmp = ve[begin];
ve[begin] = ve[i];
ve[i] = tmp;
parti(ve, begin + 1, end);
tmp = ve[begin];
ve[begin] = ve[i];
ve[i] = tmp;
}
}
}
int main()
{
vector<vector<int>> ve;
ve.resize(3);
for (int i = 1, j = 0; i < 10; i++)
{
if (!(i == 5 || i == 6 || i == 7))
ve[j].push_back(i);
if (i % 3 == 0)
{
j++;
}
}
for (int i = 0; i < 3; ++i)
{
copy(ve[i].begin(), ve[i].end(), ostream_iterator<int>(cout, " "));
cout << endl;
}
cout << endl;
//测试使用
//vector<int> a;
//a.push_back(1);
//a.push_back(2);
//a.push_back(3);
//parti(a, 0, ve.size());
//vector<vector<int>> ve1;
//ve1.resize(4);
//ve1[0].push_back(1);
//ve1[0].push_back(2);
//ve1[1].push_back(3);
//ve1[1].push_back(4);
//ve1[2].push_back(5);
//ve1[3].push_back(6);
//ve1[3].push_back(7);
vector<int> flag;
show(ve, flag, 0);
}
//模拟N个数组的遍历方式
void show(vector<vector<int>> &ve, vector<int> &flag, int k)
{
if (k < ve.size())
{
for (int i = 0; i < ve[k].size(); ++i)
{
flag.push_back(ve[k][i]);
show(ve, flag, k+1);
flag.pop_back();
}
}
if (flag.size() == ve.size())
{
//全排列
parti(flag, 0, flag.size());
cout << endl;
}
//flag.resize(0);
}
不过,感觉时间复杂度挺大的,毕竟有两层递归。