Search code examples
c++algorithmnested-loops

Define the loops at run time


consider this arrays, e.g.

#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";

}

it produces every possible combination of three vectors "aA1,...,cC3". now, I want to change it in a way that during the running, program decide number of vectors to go through (one, two, or three) and generate combination of choosen vectors. or simply, it there any way to generate a block of nested loops during the running time?


Solution

  • You can defined a recursive function along the lines of:

    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;
    }
    

    and then simply have:

    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

    assuming of course a simple print_vec function.

    You can even customize combinations more, by passing a functor that is applied to combine two elements, instead of operator+, but that's up to what you need.