Inversarea ordinii cuvintelor în C++
Inversează ordinea cuvintelor fără să inversezi literele lor. Parcurge textul din dreapta și normalizează spațiile, în char[] și std::string.
În acest material
Din Ana are mere vrem mere are Ana, păstrând literele din fiecare cuvânt în ordinea lor. Inversarea tuturor caracterelor ar produce altceva, erem era anA. Cele două cerințe nu trebuie confundate.
Ce numim cuvânt
Citim o linie cu cel mult 1000 de caractere: litere latine fără diacritice și spații obișnuite. Un cuvânt este un grup maximal de litere consecutive. La ieșire punem un singur spațiu între cuvinte și niciun spațiu la capete. Pentru o linie goală sau formată numai din spații, afișăm o linie goală.
În char s[1001], capacitatea include și terminatorul nul, caracterul \0 care marchează sfârșitul șirului C. strlen numără caracterele utile până la el. Nu citește capacitatea tabloului. În varianta string folosim size() pentru aceeași lungime a datelor din acest alfabet.
Găsim un cuvânt din dreapta
Poziția i pornește de la ultimul caracter. Sărim peste spațiile din dreapta, apoi memorăm sfârșitul cuvântului. Continuăm spre stânga până la un spațiu sau până înaintea primului caracter. Acum știm intervalul cuvântului și îl afișăm de la stânga la dreapta.
Înaintea fiecărui cuvânt, cu excepția primului afișat, scriem un spațiu. Astfel formatarea nu depinde de câte spații existau în intrare. Indicatorul primul descrie ieșirea construită, nu poziția cuvântului în textul inițial.
Textul Ana are mere devine mere are Ana. Literele fiecărui cuvânt rămân în aceeași ordine.Mărește schema ↗
Varianta cu char[]
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char s[1001]; cin.getline(s,1001);
int i=static_cast<int>(strlen(s))-1;
bool primul=true;
while(i>=0) {
while(i>=0 && s[i]==' ') --i;
if(i<0) break;
int sf=i;
while(i>=0 && s[i]!=' ') --i;
if(!primul) cout << ' ';
for(int j=i+1;j<=sf;++j) cout << s[j];
primul=false;
}
cout << '\n';
}
Varianta echivalentă cu std::string
Păstrăm aceleași limite și exemple. Șirul clasic rezervă spațiu inclusiv pentru terminatorul nul; obiectul string își gestionează memoria. Indicii caracterelor utile pornesc de la zero în ambele variante.
#include <string>
#include <iostream>
using namespace std;
int main() {
string s; getline(cin,s);
int i=static_cast<int>(s.size())-1;
bool primul=true;
while(i>=0) {
while(i>=0 && s[i]==' ') --i;
if(i<0) break;
int sf=i;
while(i>=0 && s[i]!=' ') --i;
if(!primul) cout << ' ';
for(int j=i+1;j<=sf;++j) cout << s[j];
primul=false;
}
cout << '\n';
}
Indicele trebuie să poată deveni -1
Folosim un întreg cu semn pentru parcurgerea inversă. La textul gol, lungimea convertită este 0 și scădem 1, obținând -1. Bucla nu pornește. Conversia este sigură pentru limita de 1000 de caractere; nu prezentăm această conversie ca soluție pentru texte de dimensiune arbitrară.
Verificarea i≥0 apare înaintea accesului s[i]. Operatorul && oprește evaluarea când prima condiție este falsă. La găsirea începutului unui cuvânt, i poate fi -1, iar intervalul de afișare începe corect de la i+1=0.
Fiecare caracter este parcurs de cel mult două ori, la identificare și afișare, deci timpul este O(L), unde L este lungimea textului. În afara textului, memoria suplimentară este O(1). Nu construim o listă separată de cuvinte.
Exersează
Ana are mere produce mere are Ana. abc rămâne abc. O linie de trei spații produce o linie goală. Verifică și a b, ca să observi dacă adaugi accidental un spațiu la începutul ieșirii.
Continuă cu delimitarea cuvintelor, citirea textului și operațiile pe șiruri.
Întrebări frecvente
Cum inversez ordinea cuvintelor fără să inversez literele?
Identifică grupurile care reprezintă cuvinte și afișează-le în ordine inversă, păstrând ordinea caracterelor din fiecare. Ana are mere devine mere are Ana.
Se păstrează spațiile multiple din propoziția inițială?
Nu în această lecție. Ieșirea are un singur spațiu între cuvinte și niciun spațiu la capete. Dacă formatul cere păstrarea exactă a separatorilor, algoritmul trebuie adaptat.
Ce afișez pentru o propoziție goală sau numai cu spații?
O linie goală, deoarece nu există cuvinte de inversat. Nu trebuie accesat un caracter înainte de începutul textului în încercarea de a găsi ultimul cuvânt.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.