Newsgroup: it.comp.lang.c++
Titolo: Salvare su file

Di solito per salvare su file salvo le singole informazioni (string,
int, etc...) screando una stringa formattata in modo da riconoscere i
campi e copiandola su file.
Ora ho un problema. Devo copiare su file una matrice 1000x1000 ed
ovviamente il metodo che uso di solito è troppo lento.
Avete qualcosa da consigliarmi?
Grazie,
Mic


ti do un'altra idea:
prima scrivi la matrice sul file, che sai che sarà un segmento lungo
[1000*1000*sizeof(TIPO_DATI)] bytes.
poi scrivi le stringhe terminate da un \0.
per leggere leggi la matrice 1000x1000 e poi la 1° stringa fino al \0, e la
seconda fino a \0.
ciao :o: xaero

Avete qualcosa da consigliarmi?
Dipende da come e' memorizzata la matrice, cosa sono gli
elementi, se e' una matrice sparsa (come spero) e se ti
interessa la portabilita' del file fra varie piattaforme
oppure no.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

oppure no.
E' un array i due dimensioni:
MioArray[1000][1000]
il tipo è una classe che ha due campi: una stringa e un intero.
Il mio problema non è la portabilità fra le varia piattaforme, ma
semplicemente di trovare un modo per memorizzarla su file per poi
rileggerla in un successivo momento.
Nel file scrivo una stringa e questa matrice.
Mic
PS: già che ci siamo che è una matrice sparsa?

seconda fino a \0.
Scusa la mia ignoranza, ma proprio non ti ho capito. Potresti
spiegarlo più nei particolri?
Grazie,
Mic

PS: già che ci siamo che è una matrice sparsa?
Una matrice sparsa e' una matrice in cui la maggior parte
degli elementi ha un valore "di default" (di solito in matematica
lo zero). Se gli elementi "interessanti" (perche' diversi
dal default) sono pochi a volte conviene usare strutture piu'
complesse in cui pero' sono salvati solo gli elementi interessanti.
Le matrici sparse si usano in molti contesti... immagina
ad esempio uno spreadsheet come Excel. Un foglio di lavoro
puo' avere un numero notevole di celle ma la maggior parte
di queste sara' sempre non utilizzata. Usare come struttura
dati per rappresentare un foglio elettronico un array
bidimensionale e' una follia. Anche se solo si volesse
usare un array di puntatori (in modo da tenere le celle vuote
che non puntano a niente) la quantita' di memoria necessaria
sarebbe spropositata. E' quindi importante che le celle non
usate occupino zero (non poco... proprio zero!) al limite
sacrificando un po' di occupazione in piu' per le celle usate
(che saranno comunque in percentuale ridottissima) e
rallentando un poco l'accesso alla cella (visto che non
bastera' piu' fare una semplice moltiplicazione+somma per
trovarla nella matrice).
Anche in matematica se la maggior parte degli elementi
di una matrice di grosse dimensioni e' nulla conviene
usare la forma "sparsa" per risparmiare sui calcoli;
infatti sarebbe sciocco fare milioni di inutili
moltiplicazioni per zero o di somme con zero e anche
se la struttura dati piu' complessa richiede piu'
istruzioni macchina per accedere all'elemento (i,j) il
tempo risparmiato nell'aver considerato solo gli
elementi interessanti ripaga ampiamente il costo.
In C++ non e' difficile scriversi una classe "SparseMatrix"
che si usa come un array bidimensionale ma che memorizza
solo gli elementi a cui hai effettivamente fatto accesso.
In questo modo si potrebbe risparmiare molta memoria e
tempo/spazio nel salvataggio/caricamento da disco...
ovviamente barattando questo risparmio con un accesso
all'elemento (i,j) che non avviene in tempo costante.
Usando una semplice std::map indicizzata sulla coppia
di indici si ha un accesso proporzionale al logaritmo
del numero di elementi non default della matrice sparsa
che e' probabilmente un buon compromesso fra semplicita'
di codifica (si usa std::map che e' gia' pronta) e
prestazioni/uso di risorse.
Io ho scritto un semplice esempio di questo tipo... pero'
mi accorgo che il codice che ho scritto (pur essendo
abbastanza primitivo) e' forse troppo lungo per essere
discusso qui nel dettaglio. Se sei interessato puoi
scaricarlo da:
 
http://www.netservers.com/~agriff/sparse.cpp
Ti riporto solo l'esempio di uso...
  int main()
  {
    typedef SparseMatrix<int> Mat;
    Mat m;
    for (int i=0; i<10; i++)
      for (int j=0; j<10; j++)
        m[i*43+j][j*j+i] = i+j;
 
    for (Mat::iterator i=m.begin(),e=m.end();
         i!=e;
         ++i)
    {
      std::cout << "m(" << i.row()
                << "," << i.col()
                << ") = " << *i << "\n";
    }
    return 0;
  }
Nota che nella dichiarazione della matrice m non sono
state indicate dimensioni. La matrice e' di dimensione
virtualmente infinita ed e' solo richiesto che gli
indici (i,j) siano interi (quindi sono ammessi
addirittura indici negativi!). Per l'accesso ad un
elemento della matrice si puo' usare indifferentemente
la sintassi m[i][j] oppure m(i,j).
Dopo aver impostato un po' di elementi della matrice
il programma fa un loop sui soli elementi interessanti
grazie ad un "iterator" simile nell'uso a quelli di
STL; per ogni elemento "interessante" e' possibile
conoscere la riga, la colonna e il valore.
Nota che questo esempio e' veramente semplificato
e non tiene conto di molte cose... ad esempio
assegnando valori "non interessanti" ad un elemento
della matrice l'elemento non viene eliminato e
continua ad occupare spazio (questo puo' essere o
meno un problema a seconda degli usi che si fanno
della matrice) inoltre nell'implementazione non sono
state gestite le problematiche su matrici "const" o
sull'accesso efficiente per righe/colonne.
Credo che pero' quel codice ti possa dare un'idea
delle possiblita' del C++ in quest'area.
HTH


Andrea
Ti rispondo solo ora perchè ci ho messo un po' a "digerire" le tue
informazioni.
Prima di tutto ti ringrazio per la lunga e dettagliata risposta.
Il problema l'ho risolto in questa maniera: io la matrice 1000x1000 la
visualizzo solo a pezzi 25x15 che scorrono e quindi l'unico problema
consisteva nel salvataggio. Ho creato un vector che contiene gli
elementi con la loro posizione nella matrice e salvo e leggo solo il
vettore mettendo le cose al loro posto nella matrice. Le modifiche
fatte dall'utente vengono rapresentate subito a video e memorizzate
nella matrice e nel vettore.
Che ne dici, può andare?
Ciao
Mic