Parcurgerea unui șir de caractere

Bază~14 min9 pași

De ce contează?

Imaginează-ți că citești o pancartă literă cu literă, cu degetul, de la stânga la dreapta. La fiecare literă poți decide ceva: „e vocală?", „e spațiu?", „o număr?". Asta e parcurgerea unui șir — treci o singură dată prin el și prelucrezi fiecare caracter.

Ce înseamnă parcurgerea

A parcurge un șir înseamnă a-i vizita caracterele pe rând, de la index 0 până la size()-1, și a face ceva la fiecare pas: a-l număra, a-l compara, a-l transforma. Cele mai multe probleme cu șiruri sunt, în esență, o singură parcurgere bine gândită.

Observația-cheie

Decizia importantă la orice parcurgere: ce reții între pași? Un contor (câte vocale), un maxim, ultimul caracter văzut. Restul e doar o buclă simplă.

Algoritmul pas cu pas

Să numărăm vocalele din "informatica". Parcurgem și creștem un contor când caracterul curent e o vocală:

s
i
n
f
o
r
m
a
t
i
c
a
index
0
1
2
3
4
5
6
7
8
9
10
Caracterele evidențiate sunt vocale: i, o, a, i, a → 5 vocale.
i=0  's[0]=i' vocala -> contor=1
i=1  's[1]=n' nu
i=2  's[2]=f' nu
i=3  's[3]=o' vocala -> contor=2
...
i=10 's[10]=a' vocala -> contor=5

Implementare C++

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

bool esteVocala(char c) {
    return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}

int main() {
    string s = "informatica";
    int vocale = 0;
    for (int i = 0; i < (int)s.size(); i++) {
        if (esteVocala(s[i])) {
            vocale++;
        }
    }
    cout << vocale << endl;  // 5
    return 0;
}

Parcurgerea cu for pe interval

Când nu ai nevoie de index, varianta „pe interval" e mai curată:

int vocale = 0;
for (char c : s) {        // c ia pe rand fiecare caracter
    if (esteVocala(c)) {
        vocale++;
    }
}
Indiciu

Folosește for (char c : s) când îți pasă doar de valoarea caracterului, și for (int i = ...) când ai nevoie de poziție (de exemplu să compari s[i] cu s[i-1]).

Complexitate

OperațieTimpSpațiu
O parcurgere completăO(n)O(1)

O singură trecere prin cele n caractere — nu poți mai repede dacă trebuie să te uiți la fiecare.

Greșeli frecvente

Greșeli reale la parcurgere:

  • i <= s.size() accesează s[size()], o poziție inexistentă. Corect: i < s.size().
  • s.size() e unsigned. Compară int i cu unsigned dă avertismente și, mai grav, s.size() - 1 pe șir gol devine un număr uriaș. Pune (int)s.size().
  • Numeri cuvintele numărând spațiile. Două spații consecutive, sau spații la capete, strică formula „cuvinte = spații + 1". Numără tranzițiile literă-după-spațiu.
  • Modifici lungimea în timpul buclei (ștergi caractere) fără să ajustezi indicele → sari peste caractere.

Recapitulare

  • Parcurgerea = o singură trecere de la index 0 la size()-1, prelucrând fiecare caracter.
  • Folosește indexul când compari poziții vecine; for (char c : s) când contează doar valoarea.
  • Condiția corectă e i < s.size()size() e unsigned, deci convertește la int la nevoie.

Întrebarea 1 / 3

Care e condiția corectă a buclei pentru a parcurge tot șirul `s`?