[C] esercizio stringhe:inversione parole

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

[C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Ciao a tutti, stavo ripassando un po' le stringhe, prima di studiare per bene funzioni specifiche (strtok, strcoll ecc), per ora conosco solo quelle basi.
Mi sono imbattuto in un esercizio un po' banale, ma non so se è il metodo giusto.
Praticamente data la stringa: "Questa è una stringa di prova", io devo ottenere:
"prova di stringa una è Questa".
Non posso usare funzioni specifiche,ma fare tutto a puntatori o indici di array.
Io ho scritto questo codice, vorrei sapere se secondo voi è corretto:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#include <string.h>



int main(void)
{
    char _str[100]=" Programma per invertire le parole!";
    int len;
    char *cur ;
    len=strlen(_str);
    cur=&_str[len-1];
    

    while (cur>&_str[0]) 
    {
        while (*cur!=' ' && cur>&_str[0])
        {
            cur--;
        }
        
       
        printf ("%s", cur);
        *cur='\0';
    }
 
    printf("\n");
    return 0;
}
Output:

Codice: Seleziona tutto

 parole! le invertire per Programma
se però io dichiaro la stringa così:

Codice: Seleziona tutto

char _str[100]="Programma per invertire le parole!";
Notate che non c'è uno spazio all'inizio della stringa, l'output diventa così:

Codice: Seleziona tutto

 parole! le invertire perProgramma
A prima vista sembrerebbe un errore: la parola per e Programma sono attaccate, ma secondo me non è un errore giusto?
Voi come avreste risolto?
Per i token di separazione, ho usato gli spazi.
Con funzioni apposite sarebbe stata appropriata la strtok?
ispaniko7
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 680
Iscrizione: domenica 24 agosto 2008, 21:50
Desktop: gnome-flashback-compiz
Distribuzione: Ubuntu 16.04 LTS

Re: [C] esercizio stringhe:inversione parole

Messaggio da ispaniko7 »

Ma non potresti portare la tua stringa in un vettore di stringhe e poi parti dall'ultimo indice. e stampi le parole con un for ?

Nel senso, se questa è il vettore con al stringa di partenza:

"programma per invertire le parole" -> lo trasformi in -> [ [programma], [per], [invertire], [le], [parole] ] -> poi fai un for partendo dalla fine e dovrebbe restituire -> parole le invertire per programma
Posso comandare anche il vento signore, c'è un uragano dentro di me che raderà al suolo ogni cosa se solo oserete sfidarmi.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Ma non potresti portare la tua stringa in un vettore di stringhe e poi parti dall'ultimo indice. e stampi le parole con un for ?

Nel senso, se questa è il vettore con al stringa di partenza:

"programma per invertire le parole" -> lo trasformi in -> [ [programma], [per], [invertire], [le], [parole] ] -> poi fai un for partendo dalla fine e dovrebbe restituire -> parole le invertire per programma
Non mi servirebbe salvarle in un'altro vettore a dire la verità, però ho capito cosa intendi.
Leggo i vari spazi e mi fermo e memorizzo la parola in un vettore di stringhe, poi parto dall'ultimo giusto?
Potrebbe essere un'idea, ma ripeto, non dovrei usare un vettore d'appoggio.
Tu dici salvare in un arrai di tipo:

Codice: Seleziona tutto

char reverse[][100];
Dove scorrendo le varie righe dell'array leggo le parole in modo inverso, giusto?
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C] esercizio stringhe:inversione parole

Messaggio da Claudio_F »

Potresti anche salvarle nell'array già in ordine invertito e scorrere l'array in avanti, o salvarle in uno stack e ripigliarle automaticamente in ordine inverso.

Ma il, tra virgolette, problema maggiore mi sembra la non chiara definizione di "inversione", perché alla fine sembra che a te interessi solo stamparle in ordine inverso (il che vuol dire che in realtà non hai ottenuto una stringa con le parole in ordine inverso). Anche il da farsi in presenza di spazi multipli (anche all'inizio e alla fine) non è definito.

In pratica con l'algoritmo che hai scritto il risultato che ottieni è normale, stampi in sequenza le seguenti stringhe:

Codice: Seleziona tutto

" parole!"
" le"
" invertire"
" per"
"Programma"
...e a dirla tutta le prime quattro non sono propriamente parole, ma parole precedute da uno spazio.
ispaniko7
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 680
Iscrizione: domenica 24 agosto 2008, 21:50
Desktop: gnome-flashback-compiz
Distribuzione: Ubuntu 16.04 LTS

Re: [C] esercizio stringhe:inversione parole

Messaggio da ispaniko7 »

Si ti servi di un vettore d'appoggio, con la stringa come dici tu (senza vettore) è forse un po' più complicato perchè ad esempo hai la stringa: "Gnu in not Linux" partendo dall'ultimo carattere avrai: "xuniL ton ni unG". Certo potresti inventarti qualcosa per rigirarla bene. Ma penso che col vettore d'appoggio sia più semplice. Perchè non puoi usarlo?
o salvarle in uno stack e ripigliarle automaticamente in ordine inverso.
Sono d'accordo!
Posso comandare anche il vento signore, c'è un uragano dentro di me che raderà al suolo ogni cosa se solo oserete sfidarmi.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

@ Claudio: non ti seguo, non ho capito dove non sono stato chiaro :)
input:

Codice: Seleziona tutto

 char _str[100]=" Programma per invertire le parole!";
Mi da:

Codice: Seleziona tutto

 parole! le invertire per Programma
input:

Codice: Seleziona tutto

char _str[100]=" Gila      75";
OUTPUT:

Codice: Seleziona tutto

 75      Gila
@Ispaniko: non posso solo per una regola di come è l'esercizo :)

Codice: Seleziona tutto

 char _str[100]=" Gnu in not Linux";
out:

Codice: Seleziona tutto

 Linux not in Gnu
non devo invertire le parole nel senso casa mia: aim asac ,forse non mi sono spiegato

EDIT:
o salvarle in uno stack e ripigliarle automaticamente in ordine inverso.


Sono d'accordo!
Deve/dovrebbe essere una programma senza stack, stringe di supporto ecc...Dalla stringa estraggo e stampo...
Non avrà senso dite voi, ok, ma l'esercizio che ho incontrato è così.

EDIT_2
...e a dirla tutta le prime quattro non sono propriamente parole, ma parole precedute da uno spazio.
Ecco, era quello che chiedevo...sembra un errore, ma forse se analizzi bene il codice dovrebbe (condizionale) essere giusto
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C] esercizio stringhe:inversione parole

Messaggio da Claudio_F »

La non chiarezza non è tua ma delle specifiche dell'esercizio. Infatti anche per me quello non è un errore, è il modo in cui quell'algoritmo seziona la stringa di partenza. Se per l'esercizio quel risultato è ok allora l'algoritmo è ok. Come detto, io dalle specifiche di un esercizio vorrei sapere anche come comportarmi nei corner case (ho visto un sacco di esercizi con specifiche che lasciano troppi spazi interpretativi... che sono poi quelle cose per cui un cliente a progetto terminato dice "ma io intendevo che...").

Personalmente non accetterei quell'output specificando che le parole ottenute devono essere separate da almeno uno spazio, ed eventualmente direi cosa fare con gli spazi multipli prima e dopo ogni parola, comprese quelle agli estremi.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Personalmente non accetterei quell'output specificando che le parole ottenute devono essere separate da almeno uno spazio, ed eventualmente direi cosa fare con gli spazi multipli prima e dopo ogni parola, comprese quelle agli estremi.
Vengono semplicemente mantenuti e invertiti se ho capito bene il tuo dubbio:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#include <string.h>



int main(void)
{
    char _str[100]="   Gila   75  sta facendo una prova con le stringhe     !!!!";
    int len;
    char *cur ;
    len=strlen(_str);
    cur=&_str[len-1];
    printf ("[%s]\n",_str);
    

    while (cur>&_str[0]) 
    {
        while (*cur!=' ' && cur>&_str[0])
        {
            cur--;
        }
        
       
        printf ("%s", cur);
        *cur='\0';
    }
 
    printf("\n");
    return 0;
}
Output:

Codice: Seleziona tutto

[   Gila   75  sta facendo una prova con le stringhe     !!!!]
 !!!!     stringhe le con prova una facendo sta  75   Gila  
Lo so è un esercizio un po' del menga, ma nella sua semplicità volevo sapere se era corretto.
Con stack, array, o stringhe di supporto, sarebbe stato più semplice.
Riguardo all'output sopra, ti convince?
Avatar utente
Claudio_F
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1463
Iscrizione: lunedì 28 maggio 2012, 18:49
Desktop: Mate/Gnome
Distribuzione: Ubu22.04

Re: [C] esercizio stringhe:inversione parole

Messaggio da Claudio_F »

Vengono semplicemente mantenuti e invertiti se ho capito bene il tuo dubbio:
Ok, così si che ci sono tutte le informazioni per dire se l'output è corretto oppure no (le "non parole" vanno trattate nello stesso modo delle parole). In tal caso il tuo output non è giusto, sia perché aggiunge uno spazio all'inizio, sia per lo spazio mancante nel caso visto prima. Cioè la stringa:

Codice: Seleziona tutto

"Programma per invertire le parole!"
deve dare l'output:

Codice: Seleziona tutto

"parole! le invertire per Programma"
e non:

Codice: Seleziona tutto

" parole! le invertire perProgramma"
In casi simili ho iterato sulle stringhe tenendo conto dello stato ("in parola" "fuori parola") e del numero di caratteri appartenenti allo spazio o alla parola con apposite variabili. Nell'esempio seguente la stringa originale non viene nemmeno modificata:

Codice: Seleziona tutto

#include <stdio.h>
#include <string.h>
#define  DELIMITER  ' '

int main(void)
{
    int len;    // lunghezza stringa
    int cnt;    // contatore caratteri da stampare
    int stat;   // stato: 1=sequenza di spazi 0=parola
    int nstat;  // nuovo stato
    char* cur;  // puntatore scorre stringa dalla fine all'inizio
    char* jcur; // puntatore per stampa cnt caratteri partendo da cur
    char* _str = "Not editable test string.";

    len = strlen(_str);
    if (0 == len) return 0;
    cur = _str + len - 1;
    stat = DELIMITER == *cur;
    cnt = 1;
    putchar('\"');
    while (cur > _str)
    {
        nstat = DELIMITER == *(cur - 1);
        if (stat != nstat)
        {
            stat = nstat;
            for (jcur=cur; cnt>0; cnt--){ putchar(*jcur); jcur++; }
        }
        cnt++;
        cur--;
    }
    for (jcur=cur; cnt>0; cnt--){ putchar(*jcur); jcur++; }
    printf("\"\n");
    printf("\"%s\"\n", _str);    // stampa la stringa originale
    return 0;
}
L'output è il seguente:

Codice: Seleziona tutto

"string. test editable Not"
"Not editable test string."
Ultima modifica di Claudio_F il mercoledì 4 marzo 2015, 14:11, modificato 5 volte in totale.
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Si è vero alcuni casi sono da trattare. Sta sera guardo bene.
Con funzioni di libreria cosa sarebbe stato indicato secondo te?
Grazie intanto per le risposte
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

@Claudio
deve dare l'output:

"parole! le invertire per Programma"

e non:

" parole! le invertire perProgramma"
Si, sembra sbagliato,ma se riscriviamo con un altro token:

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#include <string.h>



int main(void)
{
    char _str[100]="_programma_di_prova";
    int len;
    char *cur ;
    len=strlen(_str);
    cur=&_str[len-1];
    printf ("[%s]\n",_str);
    

    while (cur>_str) 
    {
        while (*cur!='_' && cur>_str)
        {
            cur--;
        }
        
       
        printf ("%s", cur);
        *cur='\0';
    }
 
    printf("\n");
    return 0;
}
ci accorgiamo che lo spazio all'inizio è una conseguenza naturale dell'algoritmo:
Ho cambiato lo spazio con '_' così si capisce meglio:

Codice: Seleziona tutto

char _str[100]="_programma_di_prova";
partendo dalla fine cerca il carattere _ e poi stampa la parola, quindi:
_prova
Nel caso precedente era lo spazio.
Poi logico, non è bello è come giustamente hai fatto tu, hai corretto no?
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Questa (scritta un po' di fretta), potrebbe essere la seconda versione con array d'appoggio come detto da @Ispaniko

Codice: Seleziona tutto

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[100] = "prova programma ,di gila75";
    char str_temp[100][100];
    char *cur=&str[0];
    int cont_row=0;
    int cont_col=0;
    int i,len;
    
    len=strlen(str);
   
   
    if ((str[len-1])!=' ')
    {
        str[len+1]=' ';
        str[len+2]='\0';
    }
    while (*cur!='\0') 
    {   
        while (*cur!=' ')
        {
            str_temp[cont_row][cont_col]=*cur;
            ++cur;
            ++cont_col;
        
        }

        str_temp[cont_row][cont_col]=*cur;
        cur++;
        str_temp[cont_row][cont_col+1]='\0';
        cont_row++;
        cont_col=0;
    }
    
    for (i=cont_row; i>=0; i--)
        printf ("%s",str_temp[i]);
    
    printf("\n");
    return 0;
}
EDIT: modificato il codice c'era un errore
Ma è solo un esempio, non ho curato bene se fa tutto a dovere.
Comunque ribadisco: che funzione di libreria sarebbe opportuno usare per un programma del genere?
Da quel poco che so, credo sia strtok(), giusto?
Ultima modifica di gila75 il martedì 3 marzo 2015, 21:48, modificato 2 volte in totale.
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: [C] esercizio stringhe:inversione parole

Messaggio da vbextreme »

senza considerare piu di tanto il discorso degli spazi perchè proprio non l'ho capito, si potrebbe usare la tecnica della strttok

Codice: Seleziona tutto

int main(void)
{
	char str[] = "Programma per invertire le parole!";
	char* s = str;
	
	while ( *s )
	{
		while ( *s && *s != ' ' ) ++s;
		if ( !*s ) break;
		*s++ = '\0';
		while ( *s && *s == ' ' ) ++s;
		if ( *s == ' ' ) {*s++ = '\0';}
	}
	--s;
	while ( s >= str )
	{
		while ( s >= str && *s ) --s;
		printf("%s",s+1);
		if ( s <= str ) break;
		putchar(' ');
		--s;
		while ( *s && *s == ' '); putchar(' ');
		if ( !*s ) { --s; putchar(' ');}
	}
	putchar('\n');
	
    return 0;
}
L' ho fatto giusto per fare :)
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

senza considerare piu di tanto il discorso degli spazi perchè proprio non l'ho capito, si potrebbe usare la tecnica della strttok
In breve, ma non era solo quello: con il programma che ho scritto risultava per esempio.
"stinga di prova"

output

"prova distringa"
Come noti di+stringa vengono uniti e sembrerebbe un'errore, ma per come ho scritto io, l'algoritmo in effetti fa la cosa giusta.
Poi, che sia una porcheria, quello è fuori discussione.
Grosso modo era quella la questione.
Ho compilato il tuo codice, e a mio avviso, mi sembri stampi spazi di troppo:

Codice: Seleziona tutto

char str[] = "Programma di prova";
Output:

Codice: Seleziona tutto

prova  di  Programma

poi (brevissimo OT):
la scrittura:

Codice: Seleziona tutto

while ( *s )


che equivale a :

Codice: Seleziona tutto

while (*s!=NULL)
nel nostro caso più che NULL è '\0' non peggiora un po' la leggibilità?
Ok, è più compatto, ma forse sono modi di scrivere più comuni per programmatori navigati (infatti tu lo sei :D ), ma per neofiti, non è più ostico
capire ?
Avatar utente
vbextreme
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1214
Iscrizione: domenica 12 gennaio 2014, 14:06
Desktop: lxde
Distribuzione: xubuntu 14.10

Re: [C] esercizio stringhe:inversione parole

Messaggio da vbextreme »

Null è dichiarato come (void*)0,quindi si riferisce all indirizzo e non al valore che per le stringhe dovrebbe esere scritto *s != '\0' che è la forma migliore da usare.
Per gli spazi, come dicevo prima, li ho messi a caso.
Più che altro stavo analizzando la possibilità di togliere la strlen() e cosa avrebbe implicato.
Easy framework per il linguaggio C.
vbextreme hack your life
gila75
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2739
Iscrizione: mercoledì 16 gennaio 2013, 17:28
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686
Località: Airuno(Lecco)

Re: [C] esercizio stringhe:inversione parole

Messaggio da gila75 »

Più che altro stavo analizzando la possibilità di togliere la strlen() e cosa avrebbe implicato.
Se ti riferisci al la mio programma è una correzione per evitare che:

Codice: Seleziona tutto

char str[100] = "io sono gila 75";
diventi così:

Codice: Seleziona tutto

75gila sono io
al posto di

Codice: Seleziona tutto

75 gila sono io
Ma ho scritto tutto di fretta...e chissà le imperfezioni che ho fatto.
Null è dichiarato come (void*)0,quindi si riferisce all indirizzo e non al valore che per le stringhe dovrebbe esere scritto *s != '\0' che è la forma migliore da usare.
no, quello è chiaro... io dicevo solo la forma contratta

Codice: Seleziona tutto

while (*s)
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: [C] esercizio stringhe:inversione parole

Messaggio da M_A_W_ 1968 »

Claudio_F [url=http://forum.ubuntu-it.org/viewtopic.php?p=4729173#p4729173][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:In casi simili ho iterato sulle stringhe tenendo conto dello stato ("in parola" "fuori parola") e del numero di caratteri appartenenti allo spazio o alla parola con apposite variabili.
Si veda anche, per un paio di esempi smaccatamente didattici - relativi a questioni molto simili - dai quali trarre ispirazione, questo post. :D
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 21 ospiti