Cuvinte în C++: numărare și lungime maximă
Parcurge cuvintele unei linii în C++ cu char[] și std::string. Numără cuvintele, găsește lungimea maximă și urmărește spațiile consecutive pas cu pas.
În acest material
Prelucrarea cuvintelor începe cu definirea separatorilor. În această lecție, un cuvânt este o secvență nevidă de litere englezești, iar separatorul este spațiul simplu ' '. Linia poate începe sau se poate termina cu spații și poate conține mai multe spații între două cuvinte.
Recapitulează citirea unei linii și secvențele. Nu presupune că numărul de cuvinte este numărul de spații plus unu: regula ar da rezultate greșite pentru o linie goală, pentru spații consecutive și pentru spații la capete.
Recunoaștem începutul unui cuvânt
Păstrăm lungimea secvenței curente de litere într-o variabilă curenta, inițial zero. Când citim o literă și curenta este zero, am găsit începutul unui cuvânt nou. Mărim numărul de cuvinte și apoi lungimea curentă. Când întâlnim un spațiu, resetăm doar lungimea curentă.
Următoarea linie are două spații la început, două între primele cuvinte și unul la final:
ana are mere
Ea conține trei cuvinte: ana, are, mere. Cele două spații inițiale nu creează cuvinte goale. Nici cele două spații dintre ana și are nu creează un cuvânt suplimentar. Lungimea maximă este 4.
Un cuvânt începe când întâlnim o literă și lungimea curentă este zero.O singură rulare · 12 secunde
Animația urmărește o linie mai scurtă, a bb, pentru a face vizibile toate tranzițiile. După a avem un cuvânt de lungime 1. Cele două spații lasă contorul de cuvinte neschimbat. Prima literă b începe al doilea cuvânt, iar a doua îi mărește lungimea la 2.
Maximul se actualizează și la final
După fiecare literă comparăm curenta cu maxima. Dacă am actualiza maximul numai la întâlnirea unui spațiu, am rata ultimul cuvânt atunci când linia se termină direct cu o literă. Actualizarea la fiecare pas tratează acest caz fără o operație separată după buclă.
Programul citește o linie de cel mult 200 de caractere, formată numai din literele a–z, A–Z și spații. Afișează numărul cuvintelor și lungimea celui mai lung cuvânt. Pentru o linie fără cuvinte, ambele rezultate sunt zero.
Varianta cu tablou clasic char[]
Tabloul are o poziție suplimentară pentru terminator. Bucla nu îl prelucrează. În limitele enunțului, orice caracter diferit de spațiu este o literă, deci ramura else poate continua direct cuvântul curent.
#include <iostream>
int main() {
char s[201]{};
std::cin.getline(s, 201);
int cuvinte = 0, curenta = 0, maxima = 0;
for (int i = 0; s[i] != '\0'; ++i) {
if (s[i] == ' ') {
curenta = 0;
} else {
if (curenta == 0) {
++cuvinte;
}
++curenta;
if (curenta > maxima) {
maxima = curenta;
}
}
}
std::cout << cuvinte << ' ' << maxima << '\n';
return 0;
}
Varianta cu std::string
Citirea păstrează aceleași spații, iar bucla examinează fiecare caracter al textului. Variabilele, tranzițiile și rezultatul sunt identice cu varianta clasică. Nu avem nevoie de un vector separat care să memoreze toate cuvintele.
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin, s);
int cuvinte = 0, curenta = 0, maxima = 0;
for (char c : s) {
if (c == ' ') {
curenta = 0;
} else {
if (curenta == 0) {
++cuvinte;
}
++curenta;
if (curenta > maxima) {
maxima = curenta;
}
}
}
std::cout << cuvinte << ' ' << maxima << '\n';
return 0;
}
Urmărește starea, nu doar rezultatul
După fiecare caracter, cuvinte reprezintă numărul de începuturi de cuvânt întâlnite. curenta este lungimea porțiunii de litere care se termină la poziția curentă sau zero dacă tocmai am citit un spațiu. maxima reține cea mai mare valoare atinsă de curenta până atunci.
Aceste semnificații explică de ce resetăm numai curenta. Dacă am reseta și maxima, am pierde cuvintele mai lungi întâlnite anterior. Dacă am mări contorul la fiecare literă, am număra litere, nu cuvinte. Dacă l-am mări la fiecare spațiu, am număra separatori, inclusiv pe cei consecutivi.
Parcurgerea are timp O(n) și folosește trei contori, adică O(1) memorie suplimentară față de text. Tabloul clasic rezervă 201 elemente, iar std::string își gestionează stocarea în funcție de text. Contorii de tip int sunt suficienți la limita de 200 de caractere.
Pentru taburi, semne de punctuație sau cratime trebuie schimbată definiția separatorului. Nu trata automat orice semn drept spațiu fără acordul enunțului. De exemplu, dacă am permite ana,mere în programul actual, el ar considera textul un singur cuvânt, deoarece virgula nu este separatorul declarat. Aici asemenea intrări sunt în afara contractului.
Exersează
- Ce rezultat produce linia
a bb? - Ce rezultat produce o linie formată din cinci spații?
- De ce ultimul cuvânt din
a lungeste inclus în maxim? - Cum poți afișa fiecare cuvânt pe o linie separată fără linii goale între ele?
Răspunsuri: 2 2; 0 0; maximul se actualizează după fiecare literă; afișezi literele curente și treci la linie nouă numai la sfârșitul unui cuvânt, ținând cont și de finalul întregului text.
Revino la cuprinsul capitolului sau continuă cu subprograme și recursivitate.
Un pas mai departe
Se încarcă progresul…