PDA

View Full Version : combinazione di vettori diverse dimensioni


zone77
31-07-2014, 21:12
Ciao a tutti,
sono nuovo del fourm e vi chiedo aiuto magari avete già incontrato questo problema.
Ho 3 array
string[] Array1 = {"A","B","C"}
string[] Array2 = {"D","E","F","G","H"}
string[] Array3 = {"I","J"}
...
string[] Arrayn = {....}

Vorrei tutte le loro possibili combinazioni.
cioè
+------+------+------+ +------+
|Array1|Array2|Array3| ///|Arrayn|
+------+------+------+ +------+
| A | D | I | |
| A | D | J | |
| A | E | I | |
| A | E | J | |
| A | F | I | |
| A | F | J | |
.....
fino ad arrivare a
| C | H | J | |
+------+------+------+


So che il numero di combinazioni sono
Dimensione(Array1) * Dimensione(Array2) * Dimensione(Array3) * Dimensione(Arrayn)

Ma non riesco a gestire il indici inserire correttamente il valori nella tabella sopra.

Qualcuno di voi si è mai imbattuto in una situazione del genere, magari in c#?

wingman87
01-08-2014, 07:02
Non è complicato gestire gli indici, è un po' come contare. Mi spiego meglio con un esempio, poni di voler enumerare tutti i numeri esprimibili con 3 cifre:
000
001
002
...
009
010
011
...
099
100
101
...

ora per passare al tuo caso specifico, immagina che le singole cifre siano gli indici di 3 array e inoltre immagina che questi indici siano non limitati ad una cifra sola e al tempo stesso abbiano un valore massimo (la dimensione dell'array che indicizzano - 1).
Fine. Quello che ti serve è memorizzare tutti questi indici (puoi usare un'array di interi ad esempio) e iniziare a "contare".
Per "contare" intendo che ad ogni passo incrementi l'indice più a destra. Se questo ha superato la dimensione massima lo azzeri ed incrementi l'indice immediatamente a sinistra. Se anche questo supera la dimensione massima lo azzeri ed incrementi il successivo e via così... Se l'ultimo indice supera la dimensione massima, hai terminato.

Daniels118
01-08-2014, 08:34
Oppure usi una funzione ricorsiva, che in pratica fa la stessa cosa, ma invece di avere un array per conservare gli indici, ogni indice viene salvato come "un'istanza" diversa della stessa variabile locale sullo stack.

zone77
01-08-2014, 18:00
Vorrei dire che l'ho fatta io, ma purtroppo no... :D

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>( this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] { item }));
}

con qualsiasi oggetto enumerabile...

avware
10-08-2014, 23:02
Non conosco quel linguaggio, somiglia a java ma non lo è, quindi non posso aiutarti nella sintassi.. Ad occhio sembra che tu stia cercando di eseguire un'astrazione quando non hai ancora un'implementazione funzionante. Prima trova la soluzione, poi la rendi astratta.

(Forse ho inteso male io) il tuo problema è facilmente riconducibile al funzionamento delle matrici, in questo caso di dimensione N.. quindi dovresti sapere bene che per avere le combinazioni che cerchi è sufficiente innestare N cicli for uno all'interno dell'altro.
for(a : a_array)
for(b : b_array)
for(c : c_array)
stampa(a,b,c)

Daniels118
11-08-2014, 09:22
Il suo problema è che non conosce a priori il numero di dimensioni della matrice, quindi non sa quanti cicli dovrebbe innestare, per questo serve un sistema "dinamico". Il linguaggio sembra c# + linq.

zone77
11-08-2014, 14:12
Daniels118 ha ragione non conosco a priori quanti cicli dovrei innestare....
vi posso dire che il pezzetto di codice scritto sopra funziona..