De ce contează?
Dacă știi să mergi pe o bicicletă obișnuită, știi aproape complet și să mergi pe una electrică: pedalezi la fel, virezi la fel, frânezi la fel. Nu reînveți mersul — doar adaugi un buton de asistență și o priză de încărcat. La fel stă treaba cu un șir de caractere față de un vector: aproape tot ce ai exersat pe vectori se aplică neschimbat pe text. Rămâne de adăugat doar un mic „motor electric" specific stringului.
Ideea-cheie
Un string este un vector de caractere. Nu e un tip exotic și nu cere tehnici noi: e o secvență de char-uri numerotate de la 0, exact ca un vector de numere numerotat de la 0. De aceea tot ce ai învățat să faci pe un vector se transferă direct pe un text — schimbi doar tipul elementelor, din numere în litere.
Concret, ce muți fără să schimbi nimic în felul în care gândești:
- Parcurgerea cu un singur
forde la0la lungime minus 1. - Indexarea elementului de pe poziția
i: la vectorv[i], la strings[i]. - Căutarea unui element: plimbi indexul și compari fiecare element cu cel căutat.
- Frecvențele: numeri de câte ori apare fiecare valoare — la vector într-un tablou de contoare, la string într-un tablou indexat după litere.
Aceeași schemă mentală, alt conținut în căsuțe. Nu reînveți algoritmul; doar îl aplici pe caractere.
Reflexul de antrenat: când vezi un text, gândește „vector de litere". Lungimea o afli cu s.size(), al i-lea caracter e s[i], iar parcurgerea, căutarea și numărarea frecvențelor sunt exact cele de la vectori. Dacă ai rezolvat „numără valoarea 3 în vector", știi deja „numără litera a în cuvânt" — e același for, aceeași comparație.
Cum alegi
Întrebarea practică nu e „știu tehnica?", ci „ce tip de date pun în căsuțe?". Răspunsul vine din ce conțin datele: litere și text înseamnă string; numere înseamnă un vector de valori (de exemplu un vector de întregi).
| Ai nevoie de... | Folosești | De ce |
|---|---|---|
| un cuvânt, o linie, un text | string | îți dă citire cu getline, lipire cu + și căutare cu .find din start |
| o listă de numere de prelucrat | un vector de valori (vector de întregi) | ții valori numerice și calculezi pe ele (sume, maxime, sortări) |
| să numeri litere dintr-un cuvânt | string parcurs ca vector | accesezi s[i] și numeri exact ca la frecvențele dintr-un vector |
| să citești o propoziție cu spații | string + getline | un vector de numere nu are noțiunea de „linie de text" |
Regula scurtă: text → string; numere → vector. Restul (parcurgere, indexare, căutare, frecvențe) e comun și l-ai exersat deja pe vectori.
Ce e nou la string față de vector
Stringul aduce câteva lucruri pe care vectorul de numere nu le are — exact „motorul electric" din analogie. Nu sunt algoritmi noi, sunt unelte care vin gata făcute:
- Lungime variabilă. Un vector îl declari adesea cu o capacitate fixă; un
stringse lungește și se scurtează singur când adaugi sau ștergi litere. Nu rezervi tu locurile dinainte. - Citire cu linie. Pentru un cuvânt folosești extragerea obișnuită din
cin, dar pentru o linie întreagă, cu spații, aigetline— ceva ce un vector de numere nici nu cunoaște. - Concatenare cu
+. Două texte se lipesc direct:"abc" + "de"dă"abcde". La un vector de numere+nu lipește două liste. - Comparare lexicografică. Pe
string,<și==compară conținutul în ordinea din dicționar:"ana" < "banana"pentru că'a'vine înaintea lui'b'. La vectori nu ai această comparare gata făcută. - Terminator la stilul C. Dacă lucrezi cu un șir clasic
char nume[100](nustring), capătul textului e marcat de un caracter terminator special, iar lungimea o afli custrlen, nu cu.size(). Lastring-ul din C++ scapi de această grijă.
Trei capcane apar mereu la trecerea de la vectori la texte.
Prima: tratezi stringul ca pe „altceva" și reinventezi parcurgerea. Mulți cred că textul cere o tehnică separată și caută o buclă specială. Nu există: e același for de la 0 la s.size() - 1, cu s[i] în loc de v[i]. Dacă te trezești inventând o schemă nouă, oprește-te — ai deja una, de la vectori.
A doua: uiți că s.size() este de tip unsigned. Dacă îl compari direct cu un int sau numeri invers cu int i și condiția i >= 0, riști avertismente sau chiar buclă infinită (o valoare unsigned nu coboară niciodată sub zero). Soluția: scrie int n = s.size(); o singură dată și lucrează cu n.
A treia: amesteci extragerea din cin cu getline. După ce citești un număr sau un cuvânt cu extragerea obișnuită, în buffer rămâne caracterul de linie nouă apăsat cu Enter; următorul getline îl găsește imediat și îți întoarce o linie goală. Soluția: după extragere, golește restul liniei cu cin.ignore() înainte de getline.