PDA

Visualizza la versione completa : [c\c++] Array bidimensionale con numeri casuali


VanBee
14-10-2012, 19:29
Vorre inizializzare un array bidimensionale 13*4 con 52 numeri diversi tra loro, ho scritto questo:


int array_smazzata[13][4];
srand(time(NULL));

//inizializza la smazzata
int i;
for (i=0; i<=12; ++i)
{
int j;
for(j=0; j<=3; ++j)
{
//genera numero random diverso dai precedenti
int i_random;
int bool_diverso=0;
while (!bool_diverso)
{
bool_diverso=1;
i_random=rand()%52+1;
int h;
for(h=0; h<=i; ++h)
{
int l;
for(l=0; l<=3; ++l)
{
if(i_random==array_smazzata[h][j])
{bool_diverso=0; break;}
}
if (!bool_diverso){break;}
}
}
// fine generazione
array_smazzata[i][j]=i_random;
}
}
//fine inizializzazione

int a;
int b;
for(b=0; b<=3; ++b)
{
for(a=0; a<=12; ++a)
{
printf("%2i, ", array_smazzata[a][b]);
}
printf("\n");
}


Tuttavia mi compaiono dei numeri uguali e non riesco a trovare l'errore...se qualcuno capisse dove sbaglio mi farebbe un gran favore.

YuYevon
14-10-2012, 20:43
Sicuramente questo



if(i_random==array_smazzata[h][j])


è sbagliato. Ci metterei "l" (elle) al posto di j. E va rivisto anche il resto in ogni caso: la matrice è inizializzata? Dal codice che hai postato sembra di no. Nel doppio for interno, per ogni riga (fino ad allora creata) vai a scorrere tutte le colonne, anche se gli elementi non hanno ancora un valore definito. Questo può dar luogo ad un comportamento indefinito, dato che in quegli elementi può esserci qualsiasi cosa. Un primo work-around rapido potrebbe essere inizializzare tutti gli elementi della matrice a 0, dato che tutti i valori che generi sono maggiori di 0 (ragione per la quale 0 sarebbe un valore "non possibile").
In ogni caso, se ti è concesso, ti conviene ricorrere ad un array monodimensionale gestito come un array bidimensionale. Semplificheresti molto le cose.

Senza contare, comunque, che se il tuo intento (da quello che si può intuire) è di generare un mazzo di 52 carte da gioco "mischiato" per iniziare una partita, ti conviene veramente tantissimo generarlo ordinato e poi mischiarlo generando, per un certo numero di volte, degli indici random. Fare quello che stati facendo significa fare diverse iterazioni a vuoto, soprattutto nelle fasi finali quando avrai generato quasi tutti i numeri nel range e la rand() continuerà a tirare fuori numeri già generati.

VanBee
15-10-2012, 02:23
Grazie, effettivamente avevo scambiato la j con la l.
Per il fatto dell'array monodimensionale inizialmente l'avevo scritto con un monodimensione, solo per che poi praticamente i vari cicli che mi servivano per dividere le carte erano parecchi, quindi ho deciso di metterne uno in più nell'inizializzazione ed avere già il bidimensionale. In ogni caso potrei anche genistirlo come mono.
Comunque non ho capito bene cosa intendi, in che senso lo mischio tramite degli indici?

YuYevon
15-10-2012, 22:20
Originariamente inviato da VanBee
Comunque non ho capito bene cosa intendi, in che senso lo mischio tramite degli indici?

Supponendo di voler ricorrere ad un array bidimensionale:



#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS 13
#define COLS 4
#define NTIMES 50

void generate(int array[][COLS])
{
int i, j;

for (i = 0; i < ROWS; ++i) {
for (j = 0; j < COLS; ++j) {
array[i][j] = i*COLS+j;
}
}
}

void shuffle(int array[][COLS])
{
int i, irnd1, irnd2, jrnd1, jrnd2;
int temp;

srand((unsigned int) time(NULL));
for (i = 0; i < NTIMES; ++i) {
irnd1 = rand()%ROWS;
jrnd1 = rand()%COLS;
irnd2 = rand()%ROWS;
jrnd2 = rand()%COLS;
temp = array[irnd1][jrnd1];
array[irnd1][jrnd1] = array[irnd2][jrnd2];
array[irnd2][jrnd2] = temp;
}
}

void print(int array[][COLS])
{
int i, j;

for (i = 0; i < ROWS; ++i) {
for (j = 0; j < COLS; ++j) {
printf("%-2d ", array[i][j]);
}
putchar('\n');
}
}

int main(void)
{
int array[ROWS][COLS] = {{0}};

generate(array);
puts("# before #");
print(array);
shuffle(array);
puts("\n# after #");
print(array);

return 0;
}


le coppie di indici casuali non sono necessariamente diverse, il che significa che potrebbe capitarti di swappare un elemento con sé stesso (cosa, in ogni caso, rimediabile) ma di sicuro in questo modo vai ad evitare un bel po' di iterazioni inutili, oltre a semplificare molto la logica.

Loading