How to generate an array of 3 columns where for each column there are 3 different possibilities?

1

The problem is this: In a vector I have 3 sets (A, B and C). Each set can have up to 3 distinct values (0, 1 or 2). That way I need to generate all the possible combinations for this case, with formula 3³ = 27 possibilities.

Example: print -> {0,0,1} - {0,1,0} - {0,1,1} - {1,0,0} - {1,0,1} - {1,1,0} - {1,1,1} - {0,0,2} - {0,2,0} - {2,0,0} - {0,1,2} - {0,2,1} - {1,2,1} - {...} - {2,2,2}

Does anyone have any idea how to do this? Do you know any algorithms that do this or something? It can be in Java or C# .

    
asked by anonymous 01.03.2016 / 01:38

1 answer

1

This issue is known as permutation with repetition . I searched other sources and in Portuguese to explain the problem better, but unfortunately I only found rubbish (sorry the term, but I'm referring to sites that copy poorly formatted and poorly explained content somewhere.)

As for the algorithm, this problem is usually solved more easily by using a recursive algorithm. Each call must generate the combinations for one of the positions of the set.

For example, given the set:

int[] conjunto = {0, 0, 0};

And the position p that the current call should swap, let's define a routine:

swap (int [] set, int p)

Remembering that elements of conjunto has the 0 , 1 or 2 and p values relative to the vector position, hence 0 <= p <= 2 .

Each time you implement recursion, you need to make clear what the recursion criteria are. In this case, it could be something like:

  • If p <= 2
  • Swap% with%
  • Increase% with%
  • Repeat steps 1 and 2 while p+1
  • Clear conjunto[p] (assign zero for future iterations)
  • If conjunto[p] < 3
  • Prints conjunto[p] and returns

I know it's complicated, but the idea here is that the p == 3 method will generate the combinations for a conjunto position and call itself recursively to generate the permutar position, and so on up to the limit of p . When the limit is reached, it prints the current contents and returns.

The table test would look like this:

C0 C1 C2 p
0  0  0  0    permutar(conjunto, p)
0  0  0  1      |_ permutar(conjunto, p + 1)
0  0  0  2         |_ permutar(conjunto, p + 1)
0  0  0  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  0  1  2             |_ Incrementar 'conjunto[p]'
0  0  1  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  0  2  2             |_ Incrementar 'conjunto[p]'
0  0  2  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  0  0  2             |_ Limpar 'conjunto[p]'
0  1  0  1         |_ Incrementar 'conjunto[p]'
0  1  0  2         |_ permutar(conjunto, p + 1)
0  1  0  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  1  1  2             |_ Incrementar 'conjunto[p]'
0  1  1  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  1  2  2             |_ Incrementar 'conjunto[p]'
0  1  2  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  1  0  2             |_ Limpar 'conjunto[p]'
0  2  0  1         |_ Incrementar 'conjunto[p]'
0  2  0  2         |_ permutar(conjunto, p + 1)
0  2  0  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  2  1  2             |_ Incrementar 'conjunto[p]'
0  2  1  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  2  2  2             |_ Incrementar 'conjunto[p]'
0  2  2  3             |_ permutar(conjunto, p + 1)
         3                 |_ imprime
0  2  0  2             |_ Limpar 'conjunto[p]'
0  0  0  1         |_ Limpar 'conjunto[p]'
1  0  0  0     |_ Incrementar 'conjunto[p]'
...

After the last line, this table repeats twice now with the first value p+1 and then with the value conjunto .

Note that the outermost version of 1 kept the 2 value in the first position while the recursive calls were changing the other positions, generating all permutations with possible repetition.

The Java algorithm for this looks like this:

public static void permutar(int[] conjunto, int p) {
    if (p == 3) {
        System.out.printf("{%d, %d, %d}%n", conjunto[0], conjunto[1], conjunto[2]);
    } else {
        do {
            permutar(conjunto, p + 1);
            conjunto[p]++;
        } while (conjunto[p] < 3);
        conjunto[p] = 0;
    }
}

And the call so:

public static void main(String[] args) {
    int[] conjunto = {0, 0, 0};
    permutar(conjunto, 0);
}

Note that the algorithm does exactly what is described above except that the commands may be in a somewhat different order.

Although the ideal would be that each developer was able to solve the above problems without looking at another's code, unfortunately that does not work, especially for those who are starting.

If you are studying algorithms, my suggestion is to look at implementations as above and try to understand how it works. Then go back to your editor and try to reimplement how you remember her. Even having looked at you will still probably miss some detail.

Over time, after exercising enough you may be able to create the solution to this and other types of problem without consultation. But it is a utopia and it is not correct to think that all developers can simply solve these challenges on their own. This would be like telling math students that they need to derive all the formulas again instead of consulting a book.

    
01.03.2016 / 03:30