Eliminarea spațiilor multiple dintr-un text C++
Redu spațiile consecutive la unul singur și elimină spațiile de la capete. Vezi soluții cu char[] și std::string, inclusiv pentru text gol.
În acest material
Din textul Ana are mere vrem să obținem Ana are mere. Eliminăm spațiile de la început și sfârșit, iar între două grupuri de caractere păstrăm un singur spațiu. Ordinea caracterelor și semnele de punctuație rămân neschimbate.
Ce înseamnă spațiu aici
Citim o linie de cel mult 1000 de caractere ASCII imprimabile (litere latine fără diacritice, cifre, semne de punctuație și spații). Considerăm separator doar caracterul obișnuit ' '. Tabulatorul și alte caractere albe nu fac parte din intrarea acestei probleme. O cerință care spune „orice caracter alb” ar necesita o definiție și un test diferit.
În varianta clasică, s și rezultat au capacitatea 1001. Lungimea rezultatului este p și nu depășește lungimea intrării. Celula rezultat[p] este rezervată terminatorului, nu unui caracter care se afișează.
Textul cu spații la început, la sfârșit și între cuvinte devine Ana are mere, cu un singur spațiu între cuvinte.Mărește schema ↗
Amânăm scrierea separatorului
Când întâlnim spații după un caracter deja păstrat, reținem doar că există un separator în așteptare. Îl scriem abia când apare următorul caracter care nu este spațiu. Astfel, spațiile finale nu sunt scrise niciodată. Spațiile inițiale sunt ignorate deoarece rezultatul este încă gol.
Pentru a b, după a avem un rezultat nevid. Cele trei spații activează același indicator, fără să adauge caractere. La b scriem un spațiu și apoi litera. Pentru a nu mai apare niciun caracter următor, deci rezultatul rămâne a.
Varianta cu char[]
#include <iostream>
using namespace std;
int main() {
char s[1001], rezultat[1001];
cin.getline(s,1001);
int p=0; bool spatiu=false;
for(int i=0;s[i]!='\0';++i) {
if(s[i]==' ') { if(p>0) spatiu=true; }
else {
if(spatiu) rezultat[p++]=' ';
rezultat[p++]=s[i]; spatiu=false;
}
}
rezultat[p]='\0';
cout << rezultat << '\n';
}
Varianta cu std::string
Nu gestionăm manual terminatorul. empty() verifică dacă am păstrat deja caractere, iar push_back adaugă un singur caracter. Intrarea rămâne limitată la 1000 de caractere, ca în prima variantă.
#include <iostream>
#include <string>
using namespace std;
int main() {
string s, rezultat; getline(cin,s);
bool spatiu=false;
for(char c : s) {
if(c==' ') { if(!rezultat.empty()) spatiu=true; }
else {
if(spatiu) rezultat.push_back(' ');
rezultat.push_back(c); spatiu=false;
}
}
cout << rezultat << '\n';
}
Corectitudine și complexitate
După fiecare prefix procesat, rezultatul conține textul normalizat până la ultimul caracter care nu este spațiu. Indicatorul reține doar existența unor spații după el. La final, ignorarea indicatorului elimină exact spațiile finale, fără să piardă un separator dintre două cuvinte.
Timpul este O(n), unde n este lungimea liniei. Păstrăm un rezultat de cel mult n caractere, deci memoria auxiliară este O(n). O soluție care șterge repetat din mijlocul textului poate muta aceeași parte a șirului de multe ori și ajunge la O(n²).
Exersează
Testează o linie goală, una formată numai din spații, a, a b și a b . Rezultatele sunt, în ordine, linie goală, linie goală, a, a b, a b. Pentru salut , lume, spațiul dinaintea virgulei rămâne: problema nu corectează punctuația.
Ca extensie, normalizează textul în același tablou, folosind un indice de citire și unul de scriere. Demonstrează întâi că indicele de scriere nu îl depășește pe cel de citire.
Continuă cu citirea liniilor complete, identificarea cuvintelor și operații uzuale pe șiruri.
Întrebări frecvente
Cum elimin spațiile multiple dintre cuvinte?
Păstrează caracterele în ordine și emite un singur spațiu între două grupuri de caractere. Separat, evită spațiul de la început și pe cel de la sfârșit.
Ce rezultat are un text alcătuit numai din spații?
După normalizarea din lecție, rezultatul este textul gol. Nu rămâne un spațiu, deoarece nu există două grupuri de caractere între care să fie necesar un separator.
Algoritmul elimină și tabulatorii?
Nu în contractul acestei lecții: separatorul este numai spațiul obișnuit. Dacă trebuie tratate toate caracterele albe, modifică explicit definiția separatorului și adaugă teste pentru fiecare categorie acceptată.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.