Rimozione occorrenze di caratteri in una stringa

0

Sto leggendo questo libro, Programming Interviews Exposed by John Mongan et. al e nel capitolo 6 stanno discutendo di rimuovere tutte le istanze di caratteri in una stringa src usando una stringa di rimozione, ad es. removeChars(string str, string remove) .

Suggeriscono di avere una matrice di ricerca booleana con tutti i valori inizialmente impostati su false, quindi eseguono il ciclo di ogni carattere in remove impostando il valore corrispondente nell'array di ricerca su true. (nota: questo potrebbe anche essere un hash se il set di caratteri possibile dove enorme come Unicode-16 o qualcosa del genere o se str e remove sono entrambi relativamente piccoli ... < 100 caratteri suppongo). Quindi esegui un'iterazione attraverso str con un indice di origine e di destinazione, copiando ciascun carattere solo se il suo valore corrispondente nell'array di ricerca è falso ...

Capisco la loro spiegazione, ma non capisco il loro codice. Loro hanno

for(src = 0; src < len; ++src){
   flags[r[src]] == true;
}

che gira il valore del flag sulla stringa remove indicizzata su src su true ...

quindi, se inizi con PLEASE HELP come str e LEA come rimuovi, apparirai nella tabella dei flag a 0,1,2... t|t|t , ma dopo otterrai un'eccezione fuori dai limiti perché r non lo fa avere qualcosa di più grande di 2 in esso. Anche usando il loro esempio ottieni un'eccezione fuori dai limiti. Il loro esempio di codice è impraticabile?

Funzione intera:

string removeChars( string str, string remove ){
   char[] s = str.toCharArray();
   char[] r = remove.toCharArray();
   bool[] flags = new bool[128]; // assumes ASCII!
   int len = s.Length;
   int src, dst;
   // Set flags for characters to be removed
   for( src = 0; src < len; ++src ){
      flags[r[src]] = true;
    }

   src = 0;
   dst = 0;
   // Now loop through all the characters,
   // copying only if they aren’t flagged
   while( src < len ){
       if( !flags[ (int)s[src] ] ){
       s[dst++] = s[src];
   }
   ++src;
   }
   return new string( s, 0, dst );
}

r deriva dalla stringa di rimozione. Quindi nel mio esempio la stringa di rimozione ha solo una dimensione di 3 mentre la mia stringa str ha una dimensione di 11. len è uguale alla lunghezza della stringa str , che sarebbe 11. Come posso eseguire il ciclo la stringa r poiché è solo la dimensione 3? Non ho compilato il codice per poterlo scorrere, ma solo guardandolo so che non funzionerà. Sto pensando che volessero scorrere la stringa r ... in altre parole hanno ottenuto la lunghezza della stringa sbagliata qui.

Ho ragione? Qualcuno può spiegarmelo?

    
posta SoftwareSavant 21.09.2012 - 02:20
fonte

1 risposta

4

Non c'è molto codice qui per lavorare ed è improbabile che tutti abbiano una copia di questo libro, quindi questa è una supposizione! Sarebbe utile se tu pubblicassi più codice.

Uso del PLEASE HELP & LEA esempio, scommetterei che l'array flags è una tabella di ricerca indicizzata dal valore ASCII di un carattere e alla fine assomiglierebbe a:

flags['A'] -> true
flags['B'] -> false
...
flags['E'] -> true
...
flags['L'] -> true
... (everything else would be false)

Quindi quando fai la copia rimossa la routine vedrebbe che

flags['P'] -> false, so copy it
flags['L'] -> true, so don't copy
flags['E'] -> true, so don't copy
etc

'P' è il valore ASCII del carattere P.

    
risposta data 21.09.2012 - 02:40
fonte

Leggi altre domande sui tag