Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ -
Forum - C/C++ - "Compattare" un array... - Pagina 2

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 20:29
Venerdì, 09/10/2015
Si hai ragione.

In place si potrebbe fare:

Codice sorgente - presumibilmente C++

  1. int j = 0;
  2. for (int i = 0; i < totEl; i++){
  3.     if (*pp[i] != NULL) {
  4.         pp[j++] = pp[i];
  5.     }
  6. }
  7.  
  8. // j è la nuova dimensione dell'array
  9.  
  10. return pp;



Il mio blog: https://piero.dev
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 21:49
Sabato, 10/10/2015
Grazie per i molti consigli.

Il vettore è per forza di cose "piccolino", perché si tratta di immagini che dovrebbero costituire un doppio buffer dello schermo, uno per l'offscreen del primo piano, l'altro per un secondo offscreen dal quale prelevare i dati per le cancellature (la "gomma"). Ipotizzando per le LIM il caso più comune di 1024*768 pixel di risoluzione, ogni elemento della lista verrebbe a pesare (indirettamente, perché un HBITMAP è giusto un puntatore di 4 byte) circa 1024*768*4*2 byte, ovvero circa 6 megabytes. Nei miei "piani" c'è l'idea di implementare un numero massimo di elementi che si aggirerà tra gli 8 e i 16 (non ho ancora deciso; valuterò con delle prove d'uso pratico sul campo per vedere quale può essere un tetto realisticamente utile).

Siccome si scambia la posizione degli HBITMAP senza movimentare le immagini vere e proprie, la velocità non credo proprio sia problema, particolarmente con così pochi elementi. Molto gradita invece la semplicità del procedimento, perché non voglio correre il rischio di perdermi in complicazioni che faticherei a gestire.

Detto questo, credo che ricorrerò a uno dei due metodi proposti da Piero, probabilmente il secondo. Farò qualche esperimento, quindi tornerò a dirvi com'è andata e quale codice avrò effettivamente "adottato".

Per ora, grazie di nuovo.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 23:19
Sabato, 10/10/2015
Ho inserito il metodo di compattazione come membro privato della mia classe PAGINE, con questo prototipo:

int CompattaArrayHBITMAP();

Il metodo compatta due array “paralleli” che esistono come proprietà HBITMAP *pp (primi piani) e HBITMAP *sf (sfondi) della classe, quindi restituisce il numero degli HBITMAP non NULL rilevati e compattati in testa a ciascun vettore (il valore di ritorno viene sfruttato come indicatore del numero delle pagine disponibili nella classe, immagazzinandolo in una proprietà int totPag).

LÂ’implementazione finale, dovendo gestire due array in parallelo, è un poco diversa da quella che mi ha suggerito Piero, ma ne segue strettamente la logica:

Codice sorgente - presumibilmente C#

  1. int PAGINE::CompattaArrayHBITMAP() {
  2.     int i, j;
  3.  
  4.     for( i=j=0; i<maxPag; ++i ) {
  5.         if( pp[i] != NULL ) {
  6.             pp[j] = pp[i];
  7.             sf[j] = sf[i];
  8.             ++j;
  9.         }
  10.     }
  11.  
  12.     for( i=j; i<maxPag; ++i )
  13.         pp[i] = sf[i] = NULL;
  14.  
  15.     return j; // la quantita' degli HBITMAP
  16.               // non NULL in testa agli array
  17. }



Il metodo viene impiegato esclusivamente dal metodo pubblico bool elimina_pagina( int indice ); che elimina la pagina allÂ’indice richiesto (se esiste e purché non sia lÂ’ultima disponibile):

Codice sorgente - presumibilmente C/C++

  1. bool PAGINE::elimina_pagina( int indice ) {
  2.     if( indice > -1 && indice < totPag && totPag > 1 ) {
  3.  
  4.         if( indice == iPag ) // si sta eliminando la pagina correntemente selezionata?
  5.             { SelectObject( dc_pp, pp_orig ); SelectObject( dc_sf, sf_orig ); }
  6.  
  7.         DeleteObject( pp[indice] );  pp[indice] = NULL;
  8.         DeleteObject( sf[indice] );  sf[indice] = NULL;
  9.  
  10.         totPag = CompattaArrayHBITMAP();
  11.  
  12.         seleziona_pagina( indice<iPag ? --iPag : iPag );
  13.  
  14.         return true;
  15.     }
  16.  
  17.     return false;
  18. }



Confrontando il procedimento suggerito da Piero con quello che avevo escogitato in proprio sono giunto alla conclusione che quando mÂ’è venuto in mente quellÂ’arzigogolo dovevo avere mangiato troppa peperonata (la cattiva digestione genera mostri!). In effetti la soluzione era molto più semplice di quel che mÂ’era parso lì per lì, ma per qualche ragione (la peperonata, credo) mi si era incriccato il cervello. Pirla! Meno male che cÂ’è pierotofy.it... :)

Ultima modifica effettuata da AldoBaldo il 11/10/2015 alle 12:14


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo