在运行时定义循环

时间:2015-01-26 18:28:51

标签: c++ algorithm nested-loops

考虑这个数组,例如

#include <iostream>
#include <vector>

int main(int argc, char* argv[])
{
   std::vector<char> ls(3); ls[0] = 'a'; ls[1] = 'b'; ls[2] = 'c';
   std::vector<char> us(3); us[0] = 'A'; us[1] = 'B'; us[2] = 'C';
   std::vector<int> ns(3);  ns[0] = 1;   ns[1] = 2;   ns[2] = 3;

   std::vector<char>::const_iterator lIt;
   std::vector<char>::const_iterator uIt;
   std::vector<int>::const_iterator nIt ;

   for(lIt = ls.begin(); lIt != ls.end();++lIt)
       for(uIt = us.begin();uIt != us.end();++uIt)
            for (nIt = ns.begin();nIt != ns.end();++nIt)
                std::cout << *lIt << *uIt << *nIt << "\n";

}

它产生三个向量的所有可能组合&#34; aA1,...,cC3和#34;。现在,我想以一种方式改变它,即在运行期间,程序决定要经过的矢量数量(一,二或三)并生成选择矢量的组合。或者简单地说,它有什么办法在运行时生成一个嵌套循环块?

3 个答案:

答案 0 :(得分:2)

您可以按以下方式定义递归函数:

template<class Container>
Container combinations(Container last) {
    return last;
}

template<class Container, class... Containers>
Container combinations(Container curr, Containers... rest) {
    auto ret = Container();
    for (auto i : curr)
        for (auto j : combinations(rest...))
            ret.push_back(i + j);
    return ret;
}

然后只需:

int n = /* number of vectors */;
switch (n) {
    case 1: print_vec(combinations(ls)); break;
    case 2: print_vec(combinations(ls, us)); break;
    case 3: print_vec(combinations(ls, us, ns)); break;
}

Live demo

当然假设一个简单的print_vec函数。

您甚至可以通过传递应用的仿函数来结合两个元素而不是combinations来更多地自定义operator+,但这可以达到您的需要。

答案 1 :(得分:0)

不,你不能在运行时生成一个循环块。但是使用递归可以实现类似的效果。像这样:

void emulateNestedLoops(vector<size_t>& counters, 
        const vector<pair<size_t, size_t>>& bounds, size_t depth) {
    if (depth == bounds.size()) {
        // The body of the innermost loop.
    } else {
        counters.push_back(0);
        for (size_t i = bounds[depth].first; i < bounds[depth].second; i++) {
            counters.back() = i;
            emulateNestedLoops(counters, bounds, depth + 1);
        }
        counters.pop_back();
    }
}

答案 2 :(得分:0)

所以你需要迭代recursively

这个简单的代码可以给你一些提示:

std::vector<int> manyVector[N];
int currentIndexOfEachVector[N];

void Iterate(std::vector<int> &v, int depth)
{
    if(depth==N)
    {
        for(int i=0;i<N;i++)
            std::cout<< manyVector[i][currentIndexOfEachVector[i]];
        return;
    }
    //////////////////////////////////////////////////////////////////////////
    for ( int i=0 ; i< manyVector[depth].size() ; i++ )
    {
        Iterate(manyVector[depth+1], depth+1);
    }

}


int main()
{
    Iterate(manyVector[0], 0);
    return 0;
}

如果您不喜欢静态N,则可以更改代码并使用vector of vector或动态分配manyVector