我需要一些关于如何使用数组来打印所有可能序列的想法。例如,
array 1: AA BB
array 2: CC
array 3: DD EE FF
array 4: GG
现在我需要列出来自任何给定数组的所有可能组合,每个数组只使用 1 个序列,如下所示:
AA CC DD GG
AA CC EE GG
AA CC FF GG
BB CC DD GG
BB CC EE GG
BB CC FF GG
有谁知道或可以让我开始如何做到这一点?
如果这些是 4 个不同的数组,我想不出更好的选择,然后编写 4 个嵌套循环,每个循环遍历其中一个数组。如果您有一个包含所有数组的二维数组,我建议您使用递归。
我假设您的意思是每个数组的元素数量是未知的,为此我使用了 sizeof()。就像其他人提到的那样,您只需嵌套 5 个 for 循环。
int main()
{
//naming arrays a,b,c,d,e, change accordingly
//this function prints the combinations of 1 char
int aElements = sizeof(a) / sizeof(a[0]);
int bElements = sizeof(b) / sizeof(b[0]);
int cElements = sizeof(c) / sizeof(c[0]);
int dElements = sizeof(d) / sizeof(d[0]);
int eElements = sizeof(e) / sizeof(e[0]);
for (int i = 0; i < aElements; i++){
for (int j = 0; j < bElements; j++){
for (int k = 0; k < cElements; k++){
for (int l = 0; l < dElements; l++){
for (int m = 0; m < eElements; m++){
cout << a[i] << b[j] << c[k] << d[l] << e[m] << endl;
}
}
}
}
}
}
为了找出组合的数量,您可以在内部循环中放置一个计数器,或者只需将元素的数量除以组合数量(在本例中为 1)并将它们全部相乘。例如,在您的示例中,它将是 (4 / 1) * (2 / 1) * (2 / 1) * (6 / 1) * (2 / 1) = 192 种组合。如果您每 2 个字符进行组合,则在第二个示例中它将是 (4 / 2) * (2 / 2) * (2 / 2) * (6 / 2) * (2 / 2) = 6 个组合。以下函数打印出 2 的组合。
int main()
{
//naming arrays a,b,c,d,e, change accordingly
//this function prints the combinations of 2 chars
int aElements = sizeof(a) / sizeof(a[0]);
int bElements = sizeof(b) / sizeof(b[0]);
int cElements = sizeof(c) / sizeof(c[0]);
int dElements = sizeof(d) / sizeof(d[0]);
int eElements = sizeof(e) / sizeof(e[0]);
for (int i = 0; i < aElements - 1; i+=2){
for (int j = 0; j < bElements - 1; j+=2){
for (int k = 0; k < cElements - 1; k+=2){
for (int l = 0; l < dElements - 1; l+=2){
for (int m = 0; m < eElements - 1; m+=2){
cout << a[i] << a[i+1] << b[j] << b[j+1] << c[k] << c[k+1] << d[l] << d[l+1] << e[m] << e[m+1] << endl;
}
}
}
}
}
}
我为第二次所做的只是将计数器增加 2 而不是 1,从元素数量中减去 1 以不超出界限,并打印 2 个连续元素而不是 1。这适用于任意数量的字符组合。
C++11 风格!
#include <iostream>
#include <vector>
#include <utility>
#include <iterator>
// metaprogramming boilerplate:
template<typename... L>
struct first_type {};
template<typename T, typename... L>
struct first_type<T, L...> {
typedef T type;
};
template<typename... L>
using FirstType = typename first_type<L...>::type;
namespace aux {
using std::begin;
template<typename C>
auto adl_begin( C&&c )->decltype( begin(std::forward<C>(c)) );
template<typename C>
auto adl_cbegin( C const&c )->decltype( begin(c) );
}
template<typename Container>
struct iterator_type {
typedef decltype( aux::adl_begin(std::declval<Container>()) ) iterator;
typedef decltype( aux::adl_cbegin(std::declval<Container>()) ) const_iterator;
};
template<typename Container>
using IteratorType = typename iterator_type<Container>::iterator;
template<typename Container>
struct value_type {
typedef typename std::iterator_traits< IteratorType<Container> >::value_type type;
};
template<typename Container>
using ValueType = typename value_type<Container>::type;
// Actual problem specific code:
template<typename Func, typename T>
void ForEachPossibility_Helper( Func&& f, std::vector<T>& result) {
f(result);
}
template<typename Func, typename T, typename Container, typename... Containers>
void ForEachPossibility_Helper( Func&& f, std::vector<T>& result, Container&& arr0, Containers&&... arrays) {
for( auto const& str:arr0 ) {
result.push_back(str);
ForEachPossibility_Helper( std::forward<Func>(f), result, std::forward<Containers>(arrays)... );
result.pop_back();
}
}
template<typename Func, typename... Containers>
void ForEachPossibility( Func&& f, Containers&&... arrays) {
typedef ValueType<FirstType<Containers...>> T;
std::vector<T> result;
ForEachPossibility_Helper( std::forward<Func>(f), result, std::forward<Containers>(arrays)... );
}
const char* arr1[] = {"AA", "BB"};
const char* arr2[] = {"CC"};
const char* arr3[] = {"DD", "EE", "FF"};
const char* arr4[] = {"GG"};
int main() {
ForEachPossibility( []( std::vector<const char*> const& result ){
for( auto&& str:result ) {
std::cout << str;
}
std::cout << "\n";
}, arr1, arr2, arr3, arr4 );
}
请注意,只有 2 个 for 循环,其中一个用于打印。
据我所知,您不需要关心从中获取序列的数组的顺序。在这种情况下,递归确实很有帮助。看起来像这样:
void printSequences(ListOfYourArrays list, int index) {
if (list.size() > index) {
array a = list.getElementAt(index);
//Make a cycle that reads items from your array one by one
while (...)
System.out.print(item);
//And now you need to print all combinations for the rest of arrays in you list
printSequences(list, index + 1);
} else
System.out.println();
}
您需要做的就是将您的数组添加到列表中并调用一个函数
printSequences(list, 0);
编辑更新
我们需要通过迭代组合来更新每个索引,而不是更新每个索引...
所以现在看起来像这样
#include <iostream>
#include <vector>
#include <string>
using namespace std;
bool UpdateCombination (std::vector<int> &comboindices, int count, int n)
{
for (int i = 1; i <= n; ++i)
{
if (comboindices[n - i] < count - i)
{
++comboindices[n - i];
for (int j = n - i + 1; j < n; ++j)
{
comboindices[j] = comboindices[j-1] + 1;
}
return false;
}
}
return true;
}
void ResetCombination (std::vector<int> &comboindices, int n)
{
comboindices.resize(n);
for (int i = 0; i < n; ++i)
{
comboindices[i] = i;
}
}
void PrintArrays (const std::vector<std::vector<std::string>> items, int count)
{
std::vector<std::vector<int>> indices;
int n = items.size();
indices.resize(items.size());
for(auto i = indices.begin (); i != indices.end (); ++i)
{
ResetCombination((*i),count);
}
while (true) //Iterate until we've used all of the last array of items
{
for (int i = 0; i < n; ++i)
{
cout << "{";
for (auto j = indices[i].begin (); j != indices[i].end (); ++j)
{
int ji = (*j);
cout << (items[i])[ji] << " ";
}
cout << "} ";
}
cout << endl;
//Update to the next indice
for (int i = n - 1; i >= 0; --i)
{
bool done = UpdateCombination (indices[i],items[i].size(),count);
if (!done)
{
break;
}
else if (done && i == 0)
{
return; //Escape.
}
else
{
ResetCombination(indices[i],count);
}
}
}
}
//{A,B,C,D},{A,B},{A,B},{A,B,C,D,E,F},{A,B}
int main() {
vector<vector<string>> lists;
lists.resize(5);
lists[0].push_back("A");
lists[0].push_back("B");
lists[0].push_back("C");
lists[0].push_back("D");
lists[1].push_back("A");
lists[1].push_back("B");
lists[2].push_back("A");
lists[2].push_back("B");
lists[3].push_back("A");
lists[3].push_back("B");
lists[3].push_back("C");
lists[3].push_back("D");
lists[3].push_back("E");
lists[3].push_back("F");
lists[4].push_back("A");
lists[4].push_back("B");
PrintArrays(lists,2);
int pause;
cin >> pause;
return 0;
}
给我们...
{A B } {A B } {A B } {A B } {A B }
{A B } {A B } {A B } {A C } {A B }
{A B } {A B } {A B } {A D } {A B }
{A B } {A B } {A B } {A E } {A B }
{A B } {A B } {A B } {A F } {A B }
{A B } {A B } {A B } {B C } {A B }
{A B } {A B } {A B } {B D } {A B }
{A B } {A B } {A B } {B E } {A B }
{A B } {A B } {A B } {B F } {A B }
{A B } {A B } {A B } {C D } {A B }
{A B } {A B } {A B } {C E } {A B }
{A B } {A B } {A B } {C F } {A B }
{A B } {A B } {A B } {D E } {A B }
{A B } {A B } {A B } {D F } {A B }
{A B } {A B } {A B } {E F } {A B }
{A C } {A B } {A B } {A B } {A B }
{A C } {A B } {A B } {A C } {A B }
{A C } {A B } {A B } {A D } {A B }
{A C } {A B } {A B } {A E } {A B }
{A C } {A B } {A B } {A F } {A B }
{A C } {A B } {A B } {B C } {A B }
{A C } {A B } {A B } {B D } {A B }
{A C } {A B } {A B } {B E } {A B }
{A C } {A B } {A B } {B F } {A B }
{A C } {A B } {A B } {C D } {A B }
{A C } {A B } {A B } {C E } {A B }
{A C } {A B } {A B } {C F } {A B }
{A C } {A B } {A B } {D E } {A B }
{A C } {A B } {A B } {D F } {A B }
{A C } {A B } {A B } {E F } {A B }
{A D } {A B } {A B } {A B } {A B }
{A D } {A B } {A B } {A C } {A B }
{A D } {A B } {A B } {A D } {A B }
{A D } {A B } {A B } {A E } {A B }
{A D } {A B } {A B } {A F } {A B }
{A D } {A B } {A B } {B C } {A B }
{A D } {A B } {A B } {B D } {A B }
{A D } {A B } {A B } {B E } {A B }
{A D } {A B } {A B } {B F } {A B }
{A D } {A B } {A B } {C D } {A B }
{A D } {A B } {A B } {C E } {A B }
{A D } {A B } {A B } {C F } {A B }
{A D } {A B } {A B } {D E } {A B }
{A D } {A B } {A B } {D F } {A B }
{A D } {A B } {A B } {E F } {A B }
{B C } {A B } {A B } {A B } {A B }
{B C } {A B } {A B } {A C } {A B }
{B C } {A B } {A B } {A D } {A B }
{B C } {A B } {A B } {A E } {A B }
{B C } {A B } {A B } {A F } {A B }
{B C } {A B } {A B } {B C } {A B }
{B C } {A B } {A B } {B D } {A B }
{B C } {A B } {A B } {B E } {A B }
{B C } {A B } {A B } {B F } {A B }
{B C } {A B } {A B } {C D } {A B }
{B C } {A B } {A B } {C E } {A B }
{B C } {A B } {A B } {C F } {A B }
{B C } {A B } {A B } {D E } {A B }
{B C } {A B } {A B } {D F } {A B }
{B C } {A B } {A B } {E F } {A B }
{B D } {A B } {A B } {A B } {A B }
{B D } {A B } {A B } {A C } {A B }
{B D } {A B } {A B } {A D } {A B }
{B D } {A B } {A B } {A E } {A B }
{B D } {A B } {A B } {A F } {A B }
{B D } {A B } {A B } {B C } {A B }
{B D } {A B } {A B } {B D } {A B }
{B D } {A B } {A B } {B E } {A B }
{B D } {A B } {A B } {B F } {A B }
{B D } {A B } {A B } {C D } {A B }
{B D } {A B } {A B } {C E } {A B }
{B D } {A B } {A B } {C F } {A B }
{B D } {A B } {A B } {D E } {A B }
{B D } {A B } {A B } {D F } {A B }
{B D } {A B } {A B } {E F } {A B }
{C D } {A B } {A B } {A B } {A B }
{C D } {A B } {A B } {A C } {A B }
{C D } {A B } {A B } {A D } {A B }
{C D } {A B } {A B } {A E } {A B }
{C D } {A B } {A B } {A F } {A B }
{C D } {A B } {A B } {B C } {A B }
{C D } {A B } {A B } {B D } {A B }
{C D } {A B } {A B } {B E } {A B }
{C D } {A B } {A B } {B F } {A B }
{C D } {A B } {A B } {C D } {A B }
{C D } {A B } {A B } {C E } {A B }
{C D } {A B } {A B } {C F } {A B }
{C D } {A B } {A B } {D E } {A B }
{C D } {A B } {A B } {D F } {A B }
{C D } {A B } {A B } {E F } {A B }
检查输出。 http://ideone.com/L5AZVv
老ideone链接:http: //ideone.com/58ARAZ
如果您有可变数量的数组,则 Tocs 的答案是正确的。如果你总是有 4 个数组,你可以简单地使用 4 个嵌套循环。
for (unsigned int i1 = 0; i1 < a1.size(); ++i1)
for (unsigned int i2 = 0; i2 < a2.size(); ++i2)
for (unsigned int i3 = 0; i3 < a3.size(); ++i3)
for (unsigned int i4 = 0; i4 < a4.size(); ++i4)
cout << a1[i1] << " " << a2[i2] << " " << a3[i3] << " " << a4[i4] << std::endl;
有关完整代码,请参见此处http://ideone.com/YcW84Q。
另一种可能性是“计数”当前组合(例如,计数二进制)。从 (0,0,0,0) 开始并计数到最大数组索引 (1,0,2,0)。在每一步中,首先将第一个索引加 1。如果它大于最大索引(此处为 1),则将其设置为零并继续下一个索引
结果:
(0,0,0,0) --> AA CC DD GG
(1,0,0,0) --> BB CC DD GG
(0,0,1,0) --> AA CC EE GG
(1,0,1,0) --> BB CC EE GG
(0,0,2,0) --> AA CC FF GG
(1,0,2,0) --> BB CC FF GG
4 个循环导致 N pow(4)。
拆分 4 个循环成 2 个的数组。
for each(arr 1){
for each(arr 2)
insert into container 1.
}
for each(arr 3){
for each(arr 4)
insert into container 2.
}
for each(container 1){
for each(container 2)
insert into container3 (*iter 1 + *iter 2)
}
所以复杂度最大为 3NPow(2),小于 N pow(4)