Imprimir todas as combinações de comprimento X usando recursão

dinheiro:

EXEMPLO

Dada uma matriz [1,2,3] ou [1,2,3,4], imprimir todas as combinações únicas de comprimento 3.

CÓDIGO

public class PrintCombo {

    public void printCombo(int [] a, int [] buffer, int startIndex, int bufferIndex){

        printArray(buffer);

        if(buffer.length == bufferIndex){
            System.out.println();
            System.out.println("SOLUTION START");
            printArray(buffer);
            System.out.println("SOLUTION END");
            System.out.println();
            return;
        }
        if(startIndex == a.length){
            return;
        }

        for(int i = startIndex; i<a.length; i++){
            buffer[bufferIndex] = a[i];
            printCombo(a,buffer,i+1,bufferIndex+1);
        }
    }

    public void printArray(int [] buffer){
        for(int i = 0; i<buffer.length; i++){
            System.out.print(" "+buffer[i]);
        }
        System.out.println();
    }
}

RESULTADO

Para array [1,2,3] ==> 1,2,3

Para array [1,2,3,4] ==> 1,2,3 || 1,2,4 || 1,3,4 || 2,3,4

Problema

Eu passei 3 horas traçando o código usando um depurador e ainda estou lutando para entender como a lógica recursiva está funcionando.

Por exemplo, vamos dar um exemplo, quando a matriz é [1,2,3].

  1. PrintCombo (um, tampão, 0, 0)
  2. tampão [0] é actualizada para uma
  3. Chamamos PrintCombo (um, tampão, 1, 1)
  4. tampão de [1] é actualizada para dois
  5. Chamamos PrintCombo (um, tampão, 2, 2)
  6. tampão [2] é actualizada para três
  7. Chamamos PrintCombo (um, tampão, 3, 3)
  8. Desde buffer.length == bufferIndex chamamos printArray.
  9. Nós voltar à chamada anterior

Este é o lugar onde eu me perdi. Como é que a pilha de fazer chamadas anteriores? Eu estou tentando difícil de entender essa abordagem completamente quanto eu não gosto de soluções de memorização.

I decidiu editar meu código, adicionando uma declaração de impressão para ver o que está dentro do tampão em cada iteração. Eis o que impresso, por exemplo, a = [1,2,3] e tamanho do buffer é 3.

 0 0 0
 1 0 0
 1 2 0
 1 2 3

SOLUTION START
 1 2 3
SOLUTION END

 1 3 3
 2 3 3
 2 3 3
 3 3 3
chid:

Quando inicialmente chamado de loop na printCombovontade em cada iteração definir o primeiro elemento bufferpara todos os valores possíveis:

[1,-,-]    // i = 0, first iteration
[2,-,-]    // i = 1, second iteration
[3,-,-]    // i = 2, ...
[4,-,-]    // i = 3, ...

Para cada uma dessas iterações há uma chamada recursiva para printCombocriar todas as combinações possíveis para os elementos restantes buffer. Por exemplo, na primeira iteração [1,_,_]é passado para printCombo, cuja loop irá agora definir o segundo elemento também todos os valores possíveis:

[1,2,-]    // i = 0, first iteration in first recursive call to printCombo
[1,3,-]    // i = 1, second iteration in first recursive call to printCombo
[1,4,_]    // i = 2, ...

O processo continua até que bufferé cheio (primeiro ifestado) ou a associação de possíveis valores é esgotado (segunda ifcondição). No primeiro caso um candidato é encontrada e impresso. No segundo caso um beco sem saída é atingida.

Aqui é a evolução de buffertempo ao longo do qual o nível de recuo corresponde à profundidade de recursividade ( a = [1,2,3,4]e tamanho do buffer 3):

[1,-,-]       
  [1,2,-]     
    [1,2,3]   // buffer.length == bufferIndex -> printArray
    [1,2,4]   // buffer.length == bufferIndex -> printArray
  [1,3,-]   
    [1,3,4]   // buffer.length == bufferIndex -> printArray
  [1,4,-]     // startIndex == a.length -> return 
[2,-,-]   
  [2,3,-]   
    [2,3,4]   // buffer.length == bufferIndex -> printArray
  [2,4,-]     // startIndex == a.length -> return
[3,-,-]   
  [3,4,-]     // startIndex == a.length -> return
[4,-,-]       // startIndex == a.length -> return

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=179929&siteId=1
Recomendado
Clasificación