Come fare la dimensione dinamica per i loop

1

Ho un ciclo for in C # come sotto,

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1(i);
    for(int j = 0; j < dim2.Length; j++)
    {
        DoSomething2(i, j);
        for(int k = 0; k < dim3.Length; k++)
        {
            DoSomething3(i, j, k);
        }    
    }
}

Il mio problema è che a volte la dimensione della matrice dim2 sarebbe 0, quindi DoSomething2 () e DoSomething3 () non verranno eseguiti. C'è un modo per aggirare il secondo per il ciclo se dim2.Length = 0? Cioè, quando dim2.Length = 0, voglio che i loop interi for si comportino come sotto,

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1(i);

    for(int k = 0; k < dim3.Length; k++)
    {
        DoSomething3(i, k);
    }    
}

Inoltre, i cicli for potrebbero essere di molte dimensioni (avrò dim1, dim2, dim3, dim4, ..., dimn), e fatta eccezione per la lunghezza di dim1, la lunghezza di ogni altro array potrebbe essere 0. È c'è qualche buon modo per farlo? Grazie!

    
posta Ames ISU 08.06.2016 - 22:23
fonte

2 risposte

3

Dato che la logica che si desidera eseguire è concettualmente la stessa per ogni "dimensione", e l'unica cosa che varia è l'array su cui si esegue il loop e la funzione che si chiama in quel ciclo, io userei semplicemente a funzione ricorsiva che prende gli argomenti dell'array e della funzione . Non conosco bene C #, ma presumo che il nucleo di tale approccio sia simile a questo:

public delegate void IntConsumer(List<int> ints);

public static void doStuff(List<List<int>> arrays, List<IntConsumer> consumers) {
    processArrays(arrays, consumers, new List<int>());
}

private static void processArrays(List<List<int>> arrays,
                                  List<IntConsumer> consumers,
                                  List<int> consumerArgsSoFar) {
    if(consumers.Count == 0 || arrays.Count == 0) {
        return;
    }

    List<int> currentArray = arrays[0];
    List<List<int>> remainingArrays = arrays.GetRange(1, arrays.Count-1);
    IntConsumer currentConsumer = consumers[0];
    List<IntConsumer> remainingConsumers = consumers.GetRange(1, arrays.Count-1);

    if(currentArray.Count == 0) {
        processArrays(remainingArrays, remainingConsumers, consumerArgsSoFar);
    } else {
        for(int i = 0; i < currentArray.Count; i++) {
            List<int> consumerArgs = new List<int>(consumerArgsSoFar);
            consumerArgs.Add(currentArray[i]);

            currentConsumer(consumerArgs);

            processArrays(remainingArrays, remainingConsumers, consumerArgs);
        }
    }
}

Versione completa e funzionante di questo esempio: link

Ora il numero di dimensioni dipende interamente dal chiamante di doStuff (), senza che il chiamante debba gestire una qualsiasi di queste logiche di "saltare le dimensioni vuote". Immagino sia quello che stavi cercando di ottenere, in base al tuo commento sulla risposta di Mason.

    
risposta data 08.06.2016 - 23:24
fonte
0

Is there any way to bypass the second for loop if dim2.Length = 0?

Certo. Utilizza un'istruzione if che legge esattamente esattamente come hai appena scritto:

int[] dim1, dim2, dim3;
//Initialize dim1, dim2 and dim3
for(int i = 0; i < dim1.Length; i++)
{   
    DoSomething1();

    if (dim2.Length == 0)
    {
        for(int k = 0; k < dim3.Length; k++)
        {
            DoSomething3();
        }    
    }
    else 
    {
        for(int j = 0; j < dim2.Length; j++)
        {
            DoSomething2();
            for(int k = 0; k < dim3.Length; k++)
            {
                DoSomething3();
            }    
        }
    }
}

Anche se sembra una risposta così ovvia che probabilmente manca qualcosa. Questo risolverebbe il tuo problema, o ci sono più dettagli di cui preoccuparsi?

    
risposta data 08.06.2016 - 22:34
fonte

Leggi altre domande sui tag