RISOLTO Ordine parole di una stringa al contrario

Stato
Discussione chiusa ad ulteriori risposte.

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Salve, devo realizzare una funzione che dato un array di char S inverta l'ordine delle parole e con l'aiuto di un altro array di char Y trascriva la stringa finale in S e la stampi.
Con questo codice io faccio questo.
Per esempio se S é " Ciao come stai? "
La stringa Y sarà " ?iats emoc oaiC "
In seguito S sarà " Ciao come stai? "
Non ho capito per quale motivo, a volte non mi funziona per esempio quando alla fine del file c'è l'andata a capo.
Ecco il codice
C++:
void yodizza(char S[], char Y[]) {
// Per calcolare la lunghezza si puo' fare cosi'
int lunghezza = strlen(S);

for( int i = 0; i/Ciclo che scrive l'intera stringa S al contrario in Y
{
Y[i] = S[lunghezza-1-i];
}

int wordstart, wordend, aux;

for( int i = 0; i {
wordstart = -1;
wordend = -1;
aux = -1;

if(Y[i]!=' ')
{
wordstart = i;
for( int j = wordstart; j {
if(Y[j]==' ') 
{
wordend = j-1;
break; 
}
}

if(wordend == -1) wordend = lunghezza-1;
} //L'if precedente serve a trovare la/le parola/e
else S[0+i] = ' ';

if(Y[i]!=' ')
{
aux = wordstart;

for( int k = wordend; k>=wordstart; k--,aux++)
{
S[aux] = Y[k];
}
i = wordend;

if (i+1 != lunghezza) S[i+1] = ' ';
}
}
}
[\CODE]
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
se ti è consentito usare l'header "algorithm" puoi fare così:
C++:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string s = "Ciao come stai?";
    reverse(s.begin(), s.end());
    cout << s << endl;//prints ?iats emoc oaiC
}

Se ti è consentito usare almeno l'header "string" puoi costruire una string dall'array di char passato ed avere due iterators, un forward iterator (string::begin()) che punta all'inizio ed un reverse iterator (string::rend() - 1) che punta all'ultimo char. Fai uno swap dei due elementi puntati degli iterator ed avanzi entrambi (il reverse iterator avanza al contrario, quindi quando gli dici "reverseIterator++" si sposta da (string::rend() - 1) a (string::rend() - 2). Continui fino a che gli iterator si incontrano al centro o il reverse iterator è inferiore al forward iterator.
Un singolo loop è sufficiente.
Se non puoi usare neppure string, allora la stessa cosa ma con puntatori.
Post unito automaticamente:

btw, il modo in cui stai scrivendo i for loop sopra è completamente sbagliato ed in teoria non dovrebbe neppure compilare, almeno da me non compila.
Mi riferisco a:
C++:
for (int i = 0; i{
        wordstart = -1;
        wordend = -1;
        aux = -1;

        if (Y[i] != ' ')
 
Ultima modifica:

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
se ti è consentito usare l'header "algorithm" puoi fare così:
C++:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    string s = "Ciao come stai?";
    reverse(s.begin(), s.end());
    cout << s << endl;//prints ?iats emoc oaiC
}

Se ti è consentito usare almeno l'header "string" puoi costruire una string dall'array di char passato ed avere due iterators, un forward iterator (string::begin()) che punta all'inizio ed un reverse iterator (string::rend() - 1) che punta all'ultimo char. Fai uno swap dei due elementi puntati degli iterator ed avanzi entrambi (il reverse iterator avanza al contrario, quindi quando gli dici "reverseIterator++" si sposta da (string::rend() - 1) a (string::rend() - 2). Continui fino a che gli iterator si incontrano al centro o il reverse iterator è inferiore al forward iterator.
Un singolo loop è sufficiente.
Se non puoi usare neppure string, allora la stessa cosa ma con puntatori.
Post unito automaticamente:

btw, il modo in cui stai scrivendo i for loop sopra è completamente sbagliato ed in teoria non dovrebbe neppure compilare, almeno da me non compila.
Mi riferisco a:
C++:
for (int i = 0; i{
        wordstart = -1;
        wordend = -1;
        aux = -1;

        if (Y[i] != ' ')
Non so per quale motivo mi ha mangiato quei caratteri, ti allego il codice corretto:

Codice:
void yodizza(char S[], char Y[]) {
    // Per calcolare la lunghezza si puo' fare cosi'
    int lunghezza = strlen(S);

    for( int i = 0; i<lunghezza; i++) //Ciclo che scrive l'intera stringa S al contrario in Y
    {
        Y[i] = S[lunghezza-1-i];
    }
    
    int wordstart, wordend, aux;
    
    for( int i = 0; i<lunghezza; i++)
    {
        wordstart = -1;
        wordend = -1;
        aux = -1;

        if(Y[i]!=' ')
        {
            wordstart = i;
            for( int j = wordstart; j<lunghezza; j++)
            {
                if(Y[j]==' ') 
                {
                    wordend = j-1;
                    break;    
                }
            }
            
            if(wordend == -1) wordend = lunghezza-1;
        } //L'if precedente serve a trovare la/le parola/e
        else S[0+i] = ' ';
        
        if(Y[i]!=' ')
        {
        aux = wordstart;
        
        for( int k = wordend; k>=wordstart; k--,aux++)
        {
            S[aux] = Y[k];
        }
        i = wordend;
        
        if (i+1 != lunghezza) S[i+1] = ' ';
        }
    }
}

Comunque io devo solo leggere l'ordine delle parole al contrario non l'interà stringa.

S = "Ciao Fratello"
Y = "olletarF oaiC"
S = "Fratello Ciao"
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
Comunque io devo solo leggere l'ordine delle parole al contrario non l'interà stringa.

S = "Ciao Fratello"
Y = "olletarF oaiC"
S = "Fratello Ciao"

Y = "olletarF oaiC" è decisamente l'intera stringa S al contrario.
percui se hai una funzione che ricevere una stringa e la inverte, non devi far altro che passargli prima l'intera S per ottenere Y. E poi gli passi due puntatori che sono l'inizio e la fine delle singole parole, per ogni parola.
Insomma una funzione che inverte l'ordine dei char dati due puntatori potrebbe gestire entrambi i casi
(e nel caso devi fare tutto dentro quella funzione, i loop richiesti sono gli stessi in entrambi i casi, questo è quello che intendo)

parti semplice e crea una funzione (o un loop) che inverte una string e testala per bene. Se ci riesci, hai l'80% del lavoro fatto
Post unito automaticamente:


Nel caso non fosse chiaro:

C++:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
using namespace std;



int main()
{
    string S = "Ciao Fratello :D";
    cout << "S: " << S << endl; // prints "S: Ciao Fratello :D"

    string Y = S;
    reverse(Y.begin(), Y.end());
    cout << "Y: " << Y << endl;// prints "Y: D: olletarF oaiC"

    string Z = Y;
    auto first = Z.begin();
    auto last = Z.begin();

    for(; first != Z.end(); first = last)
    {
        while (last != Z.end() && !isspace(*last)) { last++; }
        reverse(first, last);
        if (last != Z.end()) { last++; }
    }

    cout << "Z: " << Z << endl; // prints Z: ":D Fratello Ciao"
}

Come vedi il reverse gestisce tutti i casi, ed è quello che devi implementare
 
Ultima modifica:

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Ciao, scusami quando trovi lo spazio vai a salvarti la posizione in last.
Quindi se Y è "Ciao " allora last sarà 4 con i che parte da 0.
Quindi quando fai reverse(first, last) vai a fare il reverse anche dello spazio.
Quindi una stringa come "Ciao Bro" diventerebbe " BroCiao" o sbaglio?
Y = "olletarF oaiC" è decisamente l'intera stringa S al contrario.
percui se hai una funzione che ricevere una stringa e la inverte, non devi far altro che passargli prima l'intera S per ottenere Y. E poi gli passi due puntatori che sono l'inizio e la fine delle singole parole, per ogni parola.
Insomma una funzione che inverte l'ordine dei char dati due puntatori potrebbe gestire entrambi i casi
(e nel caso devi fare tutto dentro quella funzione, i loop richiesti sono gli stessi in entrambi i casi, questo è quello che intendo)

parti semplice e crea una funzione (o un loop) che inverte una string e testala per bene. Se ci riesci, hai l'80% del lavoro fatto
Post unito automaticamente:


Nel caso non fosse chiaro:

C++:
#include 
#include 
#include 
#include 
using namespace std;



int main()
{
string S = "Ciao Fratello :D";
cout / prints "S: Ciao Fratello :D"

string Y = S;
reverse(Y.begin(), Y.end());
cout / prints "Y: D: olletarF oaiC"

string Z = Y;
auto first = Z.begin();
auto last = Z.begin();

for(; first != Z.end(); first = last)
{
while (last != Z.end() && !isspace(*last)) { last++; }
reverse(first, last);
if (last != Z.end()) { last++; }
}

cout / prints Z: ":D Fratello Ciao"
}

Come vedi il reverse gestisce tutti i casi, ed è quello che devi implementare

Se ciò che ho detto è corretto andrebbe fatto il reverse da first a last-1? E dopo un controllo se i è diverso dalla fine allora aggiunge lo spazio
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
gli iterator ritornati da end() negli standard container come vector o string sono tutti uno oltre la fine, come pure quando fai robe tipo
C++:
for(int i = 0; i != vec.size(); i++)
dove size magari è 5, ma gli index vanno da 0 a 4, stessa logica
gli algoritmi nell'header algorithm trannano quel range allo stesso modo, dove tu gli passi inizio e fine e loro lavorano nel range inizio e (fine - 1)
Percui l'importante è che il tuo algoritmo lavori allo stesso modo, trattando last (il whitespace o null-character con una "C-string") come se fosse uno oltre la fine
 
  • Mi piace
Reazioni: Alessandro001

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Ok, grazie.
Tutto chiaro, scusami se non avevo capito.
Se si volesse fare la stessa cosa ma obbligatoriamente usando un array di char andrebbero implementati i singoli metodi come stavo facendo?
 
Ultima modifica:

M1n021

Nuovo Utente
144
68
Scusa, ma se si tratta di un esercizio, lo devi svolgere utilizzando stringhe C-style oppure std::string del C++? Puoi utilizzare funzioni preconfezionate oppure parte dell'esercizio consiste proprio nell'implementare le suddette funzionalità?
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
se vuoi, potresti espandere rimpiazzare ogni reverse() con un for loop, solo che avresti lo stesso loop ripetuto due volte.
Quando trovi loop che si ripetono è meglio fare il refactoring ed avere un'unica funzione, così limiti i punti nei quali potresti commettere un errore
 
  • Mi piace
Reazioni: Alessandro001

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Scusa, ma se si tratta di un esercizio, lo devi svolgere utilizzando stringhe C-style oppure std::string del C++? Puoi utilizzare funzioni preconfezionate oppure parte dell'esercizio consiste proprio nell'implementare le suddette funzionalità?
In realtà non ho vincoli e basta risolvere il problema. La soluzione migliore resta quella proposta da marcus ma vorrei sapere, per curiosità, cosa ho sbagliato nel secondo codice da me inviato nel quale implementavo le stesse funzioni ma futte in una.

Inviato da SNE-LX1 tramite App ufficiale di Tom\'s Hardware Italia Forum
 

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Esatto. Sarebbe ciò che ho fatto inizialmente giusto? Che tralaltro non capisco ancora cosa sia sbagliato
se vuoi, potresti espandere rimpiazzare ogni reverse() con un for loop, solo che avresti lo stesso loop ripetuto due volte.
Quando trovi loop che si ripetono è meglio fare il refactoring ed avere un'unica funzione, così limiti i punti nei quali potresti commettere un errore

Inviato da SNE-LX1 tramite App ufficiale di Tom\'s Hardware Italia Forum
 

Marcus Aseth

Utente Attivo
404
138
OS
Windows 10
my bad, ero quasi certo non ti fosse permesso usare algoritmi e quindi ho suggerito quel codice pensando tu dovessi comunque re-implementare reverse...non era mia intenzione suggerire direttamente la soluzione.
Sia che presenti quella soluzione o meno, ti consiglio di continuare a provare fino a che la tua singola funzione (senza l'uso di reverse()) funziona.
Parti semplice, fai in modo che riesca ad invertire una singola parola.
Quando sei sicuro che funziona, prova con le singole parole in una frase.
 
Ultima modifica:
  • Mi piace
Reazioni: Alessandro001

Alessandro001

Utente Attivo
166
7
CPU
Ryzen 5 1600 3.2GHz
Scheda Madre
MSI B350 Tomahawk
HDD
Seagate ST1000DM010 1 TB
RAM
2X8GB Corsair CMK16GX4M2B3000C15 Vengeance
GPU
RADEON RX 580 NITRO+ Radeon RX 580 8GB GDDR5
Monitor
HP 27FW Monitor 27"
PSU
Cooler Master MasterWatt Lite 700 230V
Case
Aerocool Aero-800
Net
https://www.speedtest.net/result/8773872068.png
OS
Windows 10
Grazie dell'aiuto comunque, sono riuscito a comprendere la soluzione ed ho imparato nuove metodologie di gestione delle stringhe ma anche di vector ecc.
Un ultima cosa, il tipo "auto" significa che auto determina il tipo della variabile puntata no
Alla fine auto first e auto last sono puntatori che puntano a ciò che viene restituito da S.begin() giusto?

my bad, ero quasi certo non ti fosse permesso usare algoritmi e quindi ho suggerito quel codice pensando tu dovessi comunque re-implementare reverse...non era mia intenzione suggerire direttamente la soluzione.
Sia che presenti quella soluzione o meno, ti consiglio di continuare a provare fino a che la tua singola funzione (senza l'uso di reverse()) funziona.
Parti semplice, fai in modo che riesca ad invertire una singola parola.
Quando sei sicuro che funziona, prova con le singole parole in una frase.
 

Andretti60

Utente Èlite
6,440
5,091
Scusa ma non capisco, il problema chiede di invertire l’ordine delle parole, mentre tu inverti poi anche i caratteri di ogni parola.
Mi sta sfuggendo qualcosa?
 
Stato
Discussione chiusa ad ulteriori risposte.

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili