简体   繁体   中英

How to implement a recursive function to save the elements of the N-th Cartesian Power of (0,1,...,N) in C++?

If the question is not clear, I want to have for example if N=4 a result like this:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . . . .
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . . . .
0 0 0 0 0 1 1 1 1 1 2 2 2 2 3 3 3 3 . . . .
0 1 2 3 4 0 1 2 3 4 1 2 3 4 1 2 3 4 . . . .

This is my function:

int Combinazioni(int i, int N, vector<vector<int>> & combs){ 
if(i<N) {
    for (int k=0; k<=N; k++){
            combs[i].push_back(k);
            return(Combinazioni(i+1,N, combs));
    }
    for(int j=0; j<N-1;j++){
        while(combs[j].size()<combs[N-1].size()){
            combs[j].push_back(combs[j].back());
        }
    }
} 
return 1;

}

where combs is a vector of vectors that I have initialized with N rows, and then I'll transpose it for better accessibility...

When I compile it gives me this: warning: control reaches end of non-void function [-Wreturn-type] and when I execute it prints

0
0 0
0 0 0
0 0 0 0

There must definitely be some bug in the logic of my recursion but I'm not very good at visualizing it so if there's an easy and elegant way to do this or to solve the bug I'd be grateful, thank you.

PS I think it doesn't really need to be super-efficient, and in fact if there's a better alternative to recursion, or some effective library, it would be equally fine for my purpose

Hard coded solution would look like:

std::vector<int> values{0, 1, 2, 3, 4}
for (int a1 : values) {
  for (int a2 : values) {
    for (int a3 : values) {
      for (int a4 : values) {
        for (int a5 : values) {
            do_job({a1, a2, a3, a4, a5});
        }
      }
    }
  }
}

More generic solution might be:

bool increase(std::size_t max_size, std::vector<std::size_t>& it)
{
    for (std::size_t i = 0, size = it.size(); i != size; ++i) {
        const std::size_t index = size - 1 - i;
        ++it[index];
        if (it[index] > max_size) {
            it[index] = 0;
        } else {
            return true;
        }
    }
    return false;
}

void iterate(std::size_t max_size, std::size_t len)
{
    std::vector<std::size_t> it(len, 0);

    do {
        do_job(it);
    } while (increase(max_size, it));
}

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM