Array: eliminare carattere?

di il
11 risposte

Array: eliminare carattere?

Buonasera a tutti!!

Devo e sono riuscito a creare un programma che mi chieda di inserire una parola, e in seguito inserire la lettera da togliere nella parola.a
Es: stringa : ottobre
Lettera: t
Nuova stringa: oobre

..
Il programma mi vetrebbe..Peró mi viene nel cout : 'o obre'. Come faccio a togliere i due spazzi, ovvero le due caselle dell'array in cui si trovava la lettera rimossa?

11 Risposte

  • Re: Array: eliminare carattere?

    Posta il codice.

    Comunque potrei suggerirti di salvarti l'indice della lettera tolta ed evitare che durante il ciclo questa venga visualizzata.
  • Re: Array: eliminare carattere?

    Potresti shiftare l'array verso sinistra.
  • Re: Array: eliminare carattere?

    Come già parzialmente suggerito, vi sono numerose soluzioni, non tutte di costo e prestazioni equivalenti. Ecco un breve elenco non esaustivo degli approcci logici più elementari.

    1) Cancellazione con carattere convenzionale (es. ' ') e filtraggio in fase di stampa: se la locazione corrente non contiene ' ', la si può stampare.

    2) Memorizzazione degli indici delle locazioni interessate, e filtraggio in fase di stampa: se l'indice corrente è diverso da quelli memorizzati, si può stampare la locazione corrente. Leggermente più laboriosa della 1), che richiede unicamente un confronto con un carattere convenzionale prefissato e non richiede storage aggiuntivo per memorizzare gli indici.

    3) Copia filtrata in un secondo array. Si copiano tutte le lettere in un secondo array, in ordine, tranne la lettera cercata. Aumenta il costo in storage, la complessità rimane molto bassa e comparabile con la 1).

    4) Scorrimento dell'array. Sia n la lunghezza dell'array dato e i un opportuno indice 0 <= i < n. Ogni volta che si individua nell'array la lettera cercata alla posizione i-esima, le locazioni dalla i+1 alla n vengono ordinatamente copiate nelle locazioni dalla i alla n-1, partendo ovviamente dalla locazione i+1.

    5) Scorrimento con funzioni di libreria. Esattamente come sopra, ma si usa una singola funzione come memmove() per copiare il blocco [i+1;n] nel blocco[i;n-1], poiché in questo caso destinazione e origine sono chiaramente sovrapposte in memoria.


    Le soluzioni 5) e 4) sono pessime dal punto di vista prestazionale ed è opportuno evitarle sempre, a meno di esplicite richieste didattiche.
    Le altre sono tranquillamente accettabili in un comune esercizio scolastico: come piccolo passo avanti rispetto ad una soluzione davvero pedissequa, nell'implementazione si può usare un singolo loop invece di separare le due fasi logiche di eliminazione del carattere e stampa.
  • Re: Array: eliminare carattere?

    Mi inserisco, con la massima umiltà, nella vostra discussione: quando devo eliminare un carattere ad una determinata posizione in una stringa eseguo uno strcpy() così:
    strcpy( &str, &str[i+1] ); // elimina carattere alla posizione i
    E' corretto? Il mio dubbio è quello che questo utilizzo non sia "portabile" perchè il buon funzionamento potrebbe dipendere dall'implementazione di strcpy() all'interno della libreria. Ad ogni modo non ho mai notato problemi fra i vari compilatori utilizzati nel corso degli anni... però il dubbio rimane sempre
  • Re: Array: eliminare carattere?

  • Re: Array: eliminare carattere?

    Potresti fare durante la stampa un if che controlli che l'i-simo carattere della stringa non sia uguale a ' '.
  • Re: Array: eliminare carattere?

    candaluar ha scritto:


    quando devo eliminare un carattere ad una determinata posizione in una stringa eseguo uno strcpy() così:
    strcpy( &str, &str[i+1] ); // elimina carattere alla posizione i
    E' corretto?


    Come accennavo al punto 5), l'unica funzione ufficialmente raccomandata per la gestione del caso in cui sorgente e destinazione siano sicuramente sovrapposti in memoria è la memmove(). Meglio non affidarsi alle implementazioni interne di altre funzioni nelle varie librerie di runtime.

    Inoltre è bene ricordare che questa emulazione di scorrimento in memoria, non essendo direttamente supportata dalla ISA e in hardware sulle macchine convenzionali wintel e potendo anzi generare dei cache stall, risulta prestazionalmente penalizzata e va usata con la massima cautela.


    Per l'OP: in cosa incontri esattamente difficoltà? La stampa, anche se vuoi eseguirla separatamente dalla cancellazione, deve avvenire comunque entro un loop, un carattere per volta. Se il carattere non corrisponde a ' ', viene stampato...
  • Re: Array: eliminare carattere?

    Per l'OP: in cosa incontri esattamente difficoltà? La stampa, anche se vuoi eseguirla separatamente dalla cancellazione, deve avvenire comunque entro un loop, un carattere per volta. Se il carattere non corrisponde a ' ', viene stampato...
    Come faccio a scriverlo?Grazie
    Potresti fare durante la stampa un if che controlli che l'i-simo carattere della stringa non sia uguale a ' '.
    Sì,ok, però poi quando incontra quello uguale a ' ' che faccio?
  • Re: Array: eliminare carattere?

    DavSen3 ha scritto:


    Come faccio a scriverlo?Grazie
    Esattamente come hai scritto il loop di eliminazione, con la stessa identica for() e una if all'interno... sai come inviare in output un singolo carattere della stringa usando cout? Io credo di sì.
  • Re: Array: eliminare carattere?

    Alla fine era più semplice di quanto pensassi.. Altro che shift(che era l'unica cosa che avevo in mente)
    Per correttezza lo posto:
    #include <iostream>
    using namespace std;
    
    
    void rimuove(char s[], char a)
    {
    	//char a;
    	int cont = 0;
    	for(int i=0; s[i] != '\0';i++){
    		if(s[i]== a){
    			s[i]= ' ';
    			cont = cont+1;
    		}
    		
    	}
    	cout << "Il numero delle lettere rimosse e': " <<cont <<endl;
    	for(int k=0; s[k]!='\0';k++){
    		if(s[k]!=' '){
    		cout << s[k];
    		}
    	}
    	
    	  
    }
    int main (){
    	
    	char stringa[256];
    	char a;
    	
    	cout << "Inserisci stringa" << endl;
    	cin >> stringa;
    	cout <<endl<< "Inserisci lettera da togliere"<<endl;
    	cin >> a;
    	rimuove(stringa, a);
    //	cout << "Ecco la nuova parola " <<stringa;
    
    	
    	return 0;
    	
    }
    Chiudete pure
  • Re: Array: eliminare carattere?

    Dal momento che sei arrivato fin qui, fai un ulteriore passo e cerca di concentrare tutto in un singolo loop.

    Ricorda inoltre che, quando compili in modalità C++, è opportuno usare sempre il preincremento nei loop. Purtroppo quasi tutti i compilatori generano codice peggiore (paradossalmente, a causa di un certo comportamento dell'ottimizzatore peephole) se si usa intuitivamente il postincremento.
    
        for (i = 0; ...; ++i)
    
    Inoltre, sintatticamente è preferibile evitare quella brutta assegnazione a cont, tipica di linguaggi contorti e primitivi. In C e C++ si usano gli operatori appositi.
    
    ++cont;
    cont++;
    cont +=1;
    
    La terza forma è comunque da riservare ad incrementi non unitari, per coerenza stilistica.
Devi accedere o registrarti per scrivere nel forum
11 risposte