Parcurgeri — citește fiecare caracter o dată

Bază~15 min7 pași

De ce contează?

Imaginează-ți că citești un cuvânt literă cu literă, cu degetul pe fiecare caracter, ca un copil care învață să citească. Calculatorul face exact la fel: ca să prelucreze un text, trece prin el caracter cu caracter, o singură dată.

Cum parcurgi un string

Ai două stiluri echivalente. Cu index, când ai nevoie de poziție:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s = "robot";
    for (int i = 0; i < (int)s.size(); i++) {
        cout << i << ": " << s[i] << "\n";
    }
    return 0;
}

Sau cu „range-for”, când ai nevoie doar de caractere, nu de indecși:

for (char c : s) {
    cout << c << "\n";
}
Observația-cheie

Folosește (int)s.size() în condiția for-ului. size() e fără semn; comparat direct cu un int negativ sau folosit în scăderi poate da surprize.

Caracterele sunt numere

Fiecare caracter are un cod ASCII. Literele mici, literele mari și cifrele sunt fiecare grupuri consecutive. Asta dă trucuri foarte utile:

'0'
'1'
'2'
...
'9'
48
49
50
...
57
Cifrele ocupă coduri ASCII consecutive 48…57; de aici truc-ul „- '0'”.
char c = '7';
int cifra = c - '0';        // 7  (cifra ca numar)

char litera = 'd';
int poz = litera - 'a';     // 3  (a treia litera, 0-based)

De ce funcționează? '7' - '0' calculează distanța dintre codurile ASCII. Pentru că cifrele sunt consecutive, distanța e fix valoarea cifrei.

Clasificarea caracterelor

Din <cctype> ai funcții gata făcute care întorc adevărat/fals:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string s = "Ana are 3 mere!";
    int litere = 0, cifre = 0;
    for (char c : s) {
        if (isalpha(c)) litere++;   // e litera?
        if (isdigit(c)) cifre++;    // e cifra?
    }
    cout << litere << " litere, " << cifre << " cifre\n";  // 9 litere, 1 cifre
    return 0;
}

Utile: isalpha, isdigit, isupper, islower, isspace, plus toupper și tolower pentru conversie de caz.

Exemplu: transformă tot în litere mari

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string s = "Salut, Lume";
    for (int i = 0; i < (int)s.size(); i++) {
        s[i] = toupper(s[i]);   // modifici pe loc
    }
    cout << s << "\n";          // SALUT, LUME
    return 0;
}

Complexitate

OperațieTimpSpațiu
Parcurgere simplăO(n)O(1)
Numărări / transformări pe locO(n)O(1)
Greșeli frecvente

Greșeli frecvente de concurs:

  • size() fără semn: for (int i = 0; i < s.size() - 1; ...) pe șir gol intră în buclă infinită. Folosește (int)s.size().
  • Cod ASCII în loc de valoare: (int)'7' dă 55, nu 7. Pentru cifră scrie '7' - '0'.
  • toupper pe non-litere: aplicat pe spații/cifre, le lasă neschimbate — ok, dar nu presupune că orice caracter e literă.
  • Modificarea unei copii: for (char c : s) c = toupper(c); NU schimbă s (lucrezi pe o copie). Folosește indexul sau for (char &c : s).

Recapitulare

  • Parcurgi un string cu index (când vrei poziția) sau cu for (char c : s).
  • Caracterele sunt numere ASCII; '7' - '0' și c - 'a' exploatează că grupurile sunt consecutive.
  • <cctype> îți dă isalpha, isdigit, toupper, tolower pentru clasificare.

Întrebarea 1 / 3

Pentru a transforma cifra-caracter `'7'` în numărul întreg `7`, ce scrii?