Ce conține sinteza?
Această pagină reunește tot ce trebuie reținut din modulul 2: definiții, funcții, algoritmi și reguli, într-un singur loc, pentru recapitulare rapidă.
Definițiile cheie
Șir de caractere: secvență finită de caractere, plasate într-o ordine bine stabilită; model liniar de date, în care fiecare caracter are o poziție unică, începând de la 0. Sfârșitul șirului este marcat de caracterul terminator '\0' (cod 0), care nu este nici spațiu, nici literă.
Lungimea unui șir: numărul de caractere reale, fără terminator; se află cu strlen(s). Ultimul caracter real este pe poziția n - 1.
Ordinea lexicografică: ordinea din dicționar, stabilită după prima literă diferită; un prefix vine înaintea șirului complet.
Palindrom: șir care se citește identic în ambele sensuri (ex. capac); se verifică comparând perechile simetrice până la n / 2.
Dicționar: model conceptual asociativ, o colecție de perechi cheie-valoare; în C++ se implementează cu tablouri paralele: cheia (cuvântul) și valoarea (frecvența) pe aceeași poziție.
Analogia globală: agenda de telefon
Șirul de caractere este ca un nume scris corect, literă cu literă: ordinea contează. Dicționarul este ca agenda de telefon: fiecare nume (cheia) apare o singură dată, iar lângă el stă numărul (valoarea). Funcțiile din <cstring> sunt instrumentele cu care măsurăm, copiem, lipim, căutăm și comparăm aceste nume.
Tabelul funcțiilor din cstring
Toate funcțiile de mai jos se află în biblioteca <cstring> și se folosesc în stilul BAC: #include <iostream>, #include <cstring>, using namespace std;, int main().
| Funcție | Ce face | Observație importantă |
|---|---|---|
strlen(s) |
lungimea șirului, fără terminator | salvează rezultatul într-o variabilă înainte de buclă |
strcpy(a, b) |
copiază b în a | primul argument este destinația |
strcat(a, b) |
lipește b la sfârșitul lui a | a trebuie să aibă loc suficient |
strcmp(a, b) |
compară a cu b | contează semnul: negativ, 0, pozitiv |
strchr(s, c) |
caută caracterul c | returnează pointer; poziția = p - s |
strstr(s, sub) |
caută subșirul sub | returnează NULL dacă nu există |
Reține: palindromul, conversiile șir-număr și dicționarul se implementează manual, prin parcurgere — nu există funcții speciale pentru ele.
Comparații care nu trebuie confundate
La test, o mare parte dintre greșeli vin din confundarea unor operații asemănătoare la prima vedere. Iată cele trei comparații esențiale, clar delimitate.
| Operație | Ce face | Exemplu | Greșeala frecventă |
|---|---|---|---|
strcpy(a, b) |
copiază b peste a (înlocuiește) |
strcpy(x, y); → x devine identic cu y |
a crede că strcpy lipește la sfârșit |
strcat(a, b) |
lipește b la sfârșitul lui a (adaugă) |
strcat(x, y); → x = x + y |
a uita că a trebuie să aibă loc suficient |
strcmp(a, b) |
compară conținutul șirurilor | strcmp(a, b) == 0 → sunt egale |
a scrie a == b, care compară adresele |
| șir vs. număr | un șir de cifre nu este un număr | "12" + 3 nu este 15 fără conversie |
a trata '5' ca valoarea 5, nu ca 53 |
Reține: strcpy înlocuiește, strcat adaugă, strcmp compară conținutul, iar un caracter-cifră se transformă în valoare cu s[i] - '0'.
Conversii șir-cifră și palindrom
Caracter-cifră în valoare: s[i] - '0' — codurile ASCII ale cifrelor sunt consecutive (48-57), deci diferența dă exact cifra numerică.
Șir de cifre în număr: numar = numar * 10 + (s[i] - '0'), parcurgând șirul de la stânga la dreapta.
Număr în șir: cifrele se extrag cu n % 10 de la coadă, se transformă cu cifra + '0' și se scriu în ordine inversă.
Verificarea palindromului: comparăm s[i] cu s[n - 1 - i], pentru i de la 0 la n / 2 - 1; dacă toate perechile coincid, șirul este palindrom.
Exemplu recapitulativ: pentru s = "ab2c2ba"
Lungimea este 7; perechile (a,a), (b,b), (2,2), (c,c) coincid, deci este palindrom. Cifrele sunt 2 și 2; suma lor este 4.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s[101];
cin.getline(s, 101);
int n = strlen(s);
bool palindrom = true;
for (int i = 0; i < n / 2; i++)
{
if (s[i] != s[n - 1 - i])
{
palindrom = false;
}
}
if (palindrom)
{
cout << "DA" << endl;
}
else
{
cout << "NU" << endl;
}
return 0;
}
C++ - conversiile șir-cifră, pas cu pas
Conversiile sunt operații manuale, scrise prin parcurgere — nu există funcție dedicată în <cstring>. Relația-cheie: caracterul '5' devine valoarea 5 cu '5' - '0', iar valoarea 5 devine caracter cu 5 + '0'.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char s[101];
cin.getline(s, 101);
int numar = 0;
for (int i = 0; i < strlen(s); i++)
{
numar = numar * 10 + (s[i] - '0');
}
cout << numar << endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int n = 1234;
char s[101];
int k = 0;
while (n > 0)
{
s[k] = (n % 10) + '0';
k++;
n = n / 10;
}
s[k] = '\0';
for (int i = k - 1; i >= 0; i--)
{
cout << s[i];
}
cout << endl;
return 0;
}
Observă: la conversia număr → șir, cifrele se extrag de la coadă cu n % 10, deci se scriu în ordine inversă; la final, nu uita terminatorul '\0' pe poziția k.
Dicționarul - tablouri paralele
Definiție: dicționarul este modelul asociativ cheie-valoare. Pentru frecvența cuvintelor, cheia este cuvântul, iar valoarea este numărul de apariții. În C++ folosim două tablouri paralele: cuvinte[i] și frecventa[i], cu n perechi. Un cuvânt nou se adaugă cu frecvența 1; un cuvânt existent își incrementează frecvența.
Pentru frecvența literelor, cheia este poziția în alfabet: s[i] - 'a' (un tablou cu 26 de poziții), iar litera se reconstituie cu (char)('a' + i).
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char text[1001];
cin.getline(text, 1001);
char cuvinte[501][101];
int frecventa[501] = {0};
int n = 0;
char *p = strtok(text, " ");
while (p != NULL)
{
int i;
for (i = 0; i < n; i++)
{
if (strcmp(cuvinte[i], p) == 0)
{
frecventa[i]++;
break;
}
}
if (i == n)
{
strcpy(cuvinte[n], p);
frecventa[n] = 1;
n++;
}
p = strtok(NULL, " ");
}
for (int i = 0; i < n; i++)
{
cout << cuvinte[i] << " " << frecventa[i] << endl;
}
return 0;
}
Ce învățăm: regula de aur a dicționarului: cheie găsită → creștem valoarea; cheie nouă → adăugăm pereche cu valoarea 1. Compararea cheilor se face întotdeauna cu strcmp.
Reguli de aur și greșeli frecvente
Cele mai frecvente greșeli:
- Compararea șirurilor cu
==în loc destrcmp(se compară adresele). - Tratarea lui
'\0'ca spațiu sau ca litera'0'. - Apelarea
strlenîn condiția buclei, în loc de o variabilă salvată înainte. - Uitarea
#include <cstring>sau a luicin.ignore()la citirea mixtă. - Împărțirea a două
int-uri la rapoarte, fără conversia ladouble. - Neincrementarea lui
nla adăugarea unei chei noi în dicționar.
Reguli de aur:
- Șirurile se termină cu
'\0'; declară întotdeauna un loc în plus. cin >> scitește un cuvânt;cin.getlinecitește o linie întreagă.- Pentru orice problemă de text: citește, separă, prelucrează, afișează.
- Testează pe exemple-limită: text gol, un cuvânt, cuvânt de o literă, spații multiple.
- Scrie pseudocodul înaintea codului: ordonează gândirea și aduce puncte la evaluare.
Ce trebuie să știi pentru test
Verifică-ți cunoștințele pe această listă înainte de test. Dacă poți răspunde fără să te uiți în note, ești pregătit.
Verificare rapidă:
- Ce este un șir de caractere și ce rol are terminatorul
'\0'? - Cum declari un șir pentru 100 de caractere și de ce scrii
char s[101]? - Care este diferența dintre
cin >> sșicin.getline(s, 101)? - Ce întoarce
strlen,strcpy,strcat,strcmp,strchrșistrstr? - Cum transformi caracterul
'7'în valoarea 7 și valoarea 7 în caracterul'7'? - Cum verifici dacă un cuvânt este palindrom și până unde parcurgi șirul?
- Cum numeri aparițiile cuvintelor cu tablouri paralele?
- Cum calculezi corect un procent de apariție, fără împărțire întreagă?
Recapitulare rapidă - exerciții cu rezolvare
Mini-exercițiul 1 - suma cifrelor
Enunț:
Se citește un șir format doar din cifre. Să se afișeze suma cifrelor din șir, fără a transforma șirul în număr.
Exercițiu:
Gândește întâi singur: ce condiție verifici pentru fiecare caracter și ce transformare aplici unei cifre?
Rezolvare
int suma = 0;
for (int i = 0; i < strlen(s); i++)
{
suma = suma + (s[i] - '0');
}
cout << suma << endl;Fiecare caracter-cifră se transformă în valoare cu s[i] - '0', iar valorile se adună. Pentru "123" suma este 1 + 2 + 3 = 6.
Mini-exercițiul 2 - cel mai lung cuvânt
Enunț:
Se citește un text, cu cuvintele separate prin câte un spațiu. Să se afișeze lungimea celui mai lung cuvânt.
Exercițiu:
Gândește întâi singur: ce tehnici combini (separare + lungime)? Ce variabilă reține maximul?
Rezolvare
int maxim = 0;
char *p = strtok(text, " ");
while (p != NULL)
{
if (strlen(p) > maxim)
{
maxim = strlen(p);
}
p = strtok(NULL, " ");
}
cout << maxim << endl;Separăm textul cu strtok, măsurăm fiecare cuvânt cu strlen și păstrăm în maxim cea mai mare lungime întâlnită.
Mini-exercițiul 3 - palindrom
Enunț:
Se citește un cuvânt format din litere mici. Să se afișeze DA dacă este palindrom, altfel NU.
Exercițiu:
Gândește întâi singur: până unde parcurgi șirul și ce perechi de caractere compari?
Rezolvare
int n = strlen(s);
bool palindrom = true;
for (int i = 0; i < n / 2; i++)
{
if (s[i] != s[n - 1 - i])
{
palindrom = false;
}
}
if (palindrom) cout << "DA" << endl;
else cout << "NU" << endl;Comparăm perechile simetrice doar până la n / 2; dacă toate coincid, cuvântul este palindrom.
Greșeli frecvente la test
Greșelile care costă cele mai multe puncte:
- Compararea șirurilor cu
==în loc destrcmp— se compară adresele, nu conținutul. - Lipsa
#include <cstring>sau a luicin.ignore()la citirea mixtă număr + text. - Apelarea
strlenîn condiția buclei — funcția se execută la fiecare pas. - Confuzia dintre
strcpy(înlocuiește) șistrcat(adaugă), sau ordinea greșită a argumentelor. - Tratarea caracterului
'5'ca valoarea 5: transformarea corectă este'5' - '0'. - Împărțirea întreagă la procente: 2 / 7 este 0; folosește
doubleși înmulțirea cu100.0. - Neincrementarea lui
nla adăugarea unei chei noi în dicționarul cu tablouri paralele. - Nerespectarea formatului de ieșire cerut de enunț (litere mari/mici, separatori, ordinea liniilor).
Aprofundare
Cazuri particulare și detalii avansate:
- strcmp și majusculele: literele mari (65-90) vin înaintea celor mici (97-122) în codul ASCII;
"BAC" < "bac". - Prefixele: la comparare, un șir care este prefix al altuia vine primul, pentru că
'\0'(cod 0) este mai mic decât orice literă. - Procente exacte:
double procent = (frec[i] * 100.0) / total;păstrează zecimalele. - Frecvența cuvintelor cu spații multiple:
strtokle tratează automat; la separarea manuală, ignoră cuvintele de lungime 0. - Eficiență: o singură parcurgere poate actualiza mai mulți contori (cuvinte, vocale, cifre) simultan.
Breviarul complet al modulului: orice problemă de șiruri, de la cea mai simplă la cea mai complexă, se rezolvă combinând definițiile, funcțiile și algoritmii de mai sus.