2010-02-27 11 views
5

Sto provando a lavorare con i vettori di vettori di inti per un risolutore di puzzle di sudoku che sto scrivendo.Come lavoro con i vettori annidati in C++?

Domanda 1:

Se ho intenzione di accedere a una mia 2d vettore per indice, devo inizializzare con la dimensione appropriata per primo?

Ad esempio:

typedef vector<vector<int> > array2d_t; 

void readAPuzzle(array2d_t grid) 
{ 
    for(int i = 0; i < 9; i++) 
     for(int j = 0; j < 9; j++) 
      cin >> grid[i][j]; 
    return; 
} 

int main() 
{ 
    array2d_t grid; 
    readAPuzzle(grid); 
} 

Will Seg colpa. Presumo che questo sia dovuto al fatto che sta tentando di accedere a elments di grid che non sono ancora stati inizializzati?

ho scambiato fuori riga di dichiarazione di griglia con:

array2d_t grid(9, vector<int>(9, 0)); 

e questo sembra per sbarazzarsi di questo difetto seg. È questo il modo giusto per gestirlo?

Domanda 2:

Perché è che quando provo a leggere nella mia griglia da cin, e quindi stampare la griglia, la griglia è vuota?

Sto utilizzando il seguente codice per farlo:

void printGrid(array2d_t grid) 
{ 
    for (int i = 0; i < 9; i++) 
    { 
     for (int j = 0; j < 9; j++) 
     { 
      cout << grid[i][j] + " "; 
     } 
     cout << endl; 
    } 
} 

void readAPuzzle(array2d_t grid) 
{ 
    for(int i = 0; i < 9; i++) 
     for(int j = 0; j < 9; j++) 
      cin >> grid[i][j]; 

    return; 
} 

int main() 
{ 
    array2d_t grid(9, vector<int>(9, 0)); 
    printGrid(grid); 
    readAPuzzle(grid); 
    printGrid(grid); 
} 

E io tentare di eseguire il mio programma come:

./a.out < sudoku-test 

Dove sudoku-test è un file che contiene quanto segue:

3 0 0 0 0 0 0 0 0 
5 8 4 0 0 2 0 3 0 
0 6 0 8 3 0 0 7 5 
0 4 1 0 0 6 0 0 0 
7 9 0 0 2 0 0 5 1 
0 0 0 9 0 0 6 8 0 
9 3 0 0 1 5 0 4 0 
0 2 0 4 0 0 5 1 8 
0 0 0 0 0 0 0 0 6 

La prima chiamata a printGrid() fornisce una griglia vuota, quando invece dovrei vedere una griglia 9x9 di 0 poiché è così che l'ho inizializzato. La seconda chiamata dovrebbe contenere la griglia sopra. Tuttavia, entrambe le volte è vuoto.

Qualcuno può far luce su questo?

+0

cassa boost.multi_array se si desidera modo più semplice per trattare con i dati multidimensionali dinamici – Anycorn

risposta

5

Q1: Sì, questo è il modo corretto di gestirlo. Tuttavia, si noti che i vettori annidati sono un modo piuttosto inefficiente per implementare un array 2D. Un vettore e calcolare gli indici di x + y * width è di solito un'opzione migliore.

Q2A: il calcolo di grid[i][j] + " " non concatena due stringhe (perché il lato sinistro è int, non una stringa), ma aggiunge il valore numerico a un puntatore (l'indirizzo di memoria del primo carattere della stringa ""). Utilizzare invece cout << grid[i][j] << " ".

Q2B: Si sta passando la matrice per valore (viene copiata) per readAPuzzle. La funzione legge nella sua copia locale, che viene distrutta quando la funzione ritorna. Passare per riferimento invece (questo evita di fare una copia e utilizza l'originale invece):

void readAPuzzle(array2d_t& grid) 
+0

@Tronic, ah vedo. Ho pensato che il comportamento predefinito per i vettori sarebbe passato per riferimento, come fanno gli array. – Salaban

+0

Questo non spiega perché il primo printGrid() non mi dia una griglia 9x9 di 0?Se è copiato, lo zero dovrebbe essere ancora presente durante la stampa. – Salaban

+0

Gli array sono uno strano caso speciale. Non direi che gli array vengono passati per riferimento, ma piuttosto che quando scrivi [], ottieni effettivamente un puntatore (che viene quindi passato per valore). È una questione di prospettiva, però. – Tronic