Șiruri de caractere

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.

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.

Linia a urmată de două spații și bb are două cuvinte. Contorul crește la prima literă din fiecare cuvânt, iar lungimea maximă ajunge la 2.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ă

  1. Ce rezultat produce linia a bb?
  2. Ce rezultat produce o linie formată din cinci spații?
  3. De ce ultimul cuvânt din a lung este inclus în maxim?
  4. 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…

Exersează cu o problemă →