Șiruri de caractere
Ideile de bază pe scurt și, unde există, exercițiile din subiectele de BAC care le verifică. Lecția completă, animată, cu grile și exerciții corectate, e în aplicația Tomomi.
Pe scurt
Sintaxă: citirea și afișarea unui șir
Forma canonică: capacitatea se declară o dată, cuvântul se citește cu >>, lungimea se află cu strlen, copierea se face cu strcpy:
char s[21];
cin >> s;
int n = strlen(s);
char d[21];
strcpy(d, s);Capcana: lungimea nu este capacitatea
Pentru char s[10] = "bac";, strlen(s) este 3, nu 10: capacitatea rezervă celule, dar strlen numără doar literele până la terminatorul '\0'. Terminatorul stă mereu pe poziția egală cu lungimea și nu se numără în ea. Și cin >> s se oprește la primul spațiu: citește un singur cuvânt.
Șablon: numărarea vocalelor
Parcurgi fiecare caracter și aplici testul de vocală:
int cnt = 0;
for (int i = 0; i < n; i++) {
if (s[i] == 'a' || s[i] == 'e' ||
s[i] == 'i' || s[i] == 'o' ||
s[i] == 'u') {
cnt = cnt + 1;
}
}
// consoane: același test, negatCapcana: - 32 fără test strică șirul
s[i] - 32 face litera mare, dar numai dacă s[i] este literă mică. Aplicat fără if (s[i] >= 'a' && s[i] <= 'z'), transformă și cifrele, semnele și literele deja mari în caractere de după 'z'. Testul mai întâi, transformarea după.
Șablon: verificarea palindromului
Fanion + perechi oglindite, jumătate de buclă:
int ok = 1;
for (int i = 0; i < n / 2; i++) {
if (s[i] != s[n - 1 - i]) {
ok = 0;
}
}Idee: oglinda n - 1 - i
Poziția n - 1 - i este oglinda poziției i: 0 cu ultima, 1 cu penultima. Este aceeași mișcare de la vectori (inversare, palindrom) și reapare peste tot la șiruri. La n impar, poziția din mijloc se oglindește în sine și nu are nevoie de test.
Sintaxă: familia <cstring>
Apelurile de bază, una lângă alta - destinația este mereu primul parametru:
strcpy(d, s); // d = s
strcat(d, s); // d = d + s
strcmp(a, b); // <0, 0, >0
strchr(s, 'a'); // prima aparitie
strstr(s, sub); // cauta subsirulCapcana: parametri inversați și == -1
La strcpy(d, s) și strcat(d, s), destinația este primul parametru - strcpy(s, d) copiază în sens greșit și distruge sursa. Iar strcmp întoarce diferența codurilor (<0, 0, >0), nu -1/0/1: testul strcmp(a, b) == -1 este greșit, corect este < 0. Și s == "abc" compară adresele, nu conținutul.
Șablon: extragere, inserare, eliminare
Extragi lg caractere de la poziția poz (atenție la terminator):
for (int i = 0; i < lg; i++) {
sub[i] = s[poz + i];
}
sub[lg] = '\0';Inserezi la poziția poz mutând de la COADĂ spre început; elimini mutând de la început spre coadă:
for (int i = lg; i >= poz; i--) {
s[i + 1] = s[i];
}
s[poz] = c;Șablon: conversia șir - număr
Din șir de cifre în valoare numerică (- '0' este obligatoriu):
int nr = 0;
for (int i = 0; s[i] != '\0'; i++) {
nr = nr * 10 + (s[i] - '0');
}Invers, din număr în șir: n % 10 + '0' dă caracterul ultimei cifre, n / 10 trece mai departe, iar la final oglindești șirul obținut.
Din subiectele de BAC
Exerciții reale din subiectele anilor trecuți. Încearcă-le singur înainte să deschizi rezolvarea.
Un cuvânt semioglindit se obține dintr-un cuvânt cu () litere, prin interschimbarea în acesta a secvenței formate din primele litere cu secvența formată din ultimele litere.
Exemplu: din cuvântul platim se obține cuvântul semioglindit timpla.
Într-un text de cel mult 200 de caractere, cuvintele sunt formate din litere mici ale alfabetului englez și sunt separate prin câte un spațiu. Scrieți un program C/C++ care citește de la tastatură un text de tipul precizat, pe care îl transformă în memorie, prin înlocuirea fiecărui cuvânt cu număr par de litere, cu cel semioglindit obținut din acesta, ca în exemplu. Programul afișează pe ecran textul obținut, sau mesajul nu exista, dacă toate cuvintele au număr impar de litere.
Exemplu: pentru textul am facut fotografii unei flori mari se afișează pe ecran textul ma facut rafiifotog eiun flori rima.
Vezi rezolvarea
Parcurgem textul cuvânt cu cuvânt, delimitând fiecare cuvânt între poziția lui de început și primul spațiu care urmează. Pentru un cuvânt de lungime pară , salvăm prima jumătate într-un tablou auxiliar, mutăm a doua jumătate în față și punem jumătatea salvată la sfârșit - transformarea se face în memorie, în același șir.
#include <iostream>
#include <cstring>
using namespace std;
char t[205], aux[105];
int main()
{
cin.getline(t, 205);
int n = strlen(t), i = 0, j, lg, k, p, ok = 0;
while (i < n)
{
j = i;
while (j < n && t[j] != ' ')
j++;
lg = j-i;
if (lg%2 == 0)
{
ok = 1;
k = lg/2;
for (p = 0; p < k; p++)
aux[p] = t[i+p];
for (p = 0; p < k; p++)
t[i+p] = t[i+k+p];
for (p = 0; p < k; p++)
t[i+k+p] = aux[p];
}
i = j+1;
}
if (ok)
cout << t;
else
cout << "nu exista";
return 0;
}Lungimea cuvântului nu se schimbă prin interschimbare, deci textul poate fi modificat pe loc, fără să fie nevoie de un al doilea șir pentru rezultat. Variabila ok reține dacă a existat măcar un cuvânt cu număr par de litere; dacă nu, se afișează mesajul cerut.
Într-un text, de cel mult 100 de caractere, cuvintele sunt formate din litere ale alfabetului englez și sunt separate prin câte un spațiu. Textul are cel puțin două cuvinte.
Scrieți un program C/C++ care citește de la tastatură un text de tipul precizat mai sus și afișează pe ecran mesajul DA și un număr natural n, separate printr-un spațiu, dacă toate cuvintele din text au câte n litere, sau mesajul NU în cazul în care nu toate cuvintele au același număr de litere.
Exemplu: dacă textul citit este Ana are cel mai bun mar se afișează pe ecran DA 3, iar dacă textul citit este Ana are cel mai dulce mar se afișează pe ecran NU.
Vezi rezolvarea
Citim întregul rând (textul conține spații), apoi parcurgem caracterele și numărăm lungimea fiecărui cuvânt; prima lungime devine reper, iar orice lungime diferită invalidează proprietatea.
#include <iostream>
using namespace std;
int main()
{
char s[101];
cin.getline(s, 101);
int n = -1, lg = 0, ok = 1, i;
for (i = 0; s[i] != '\0'; i++)
{
if (s[i] == ' ')
{
if (n == -1) n = lg;
else if (lg != n) ok = 0;
lg = 0;
}
else
lg++;
}
if (n == -1) n = lg;
else if (lg != n) ok = 0;
if (ok)
cout << "DA " << n;
else
cout << "NU";
return 0;
}La fiecare spațiu comparăm lungimea cuvântului tocmai încheiat cu reperul n (prima lungime întâlnită); nu uităm ultimul cuvânt, care nu este urmat de spațiu. Pentru "Ana are cel mai bun mar" toate lungimile sunt 3, deci se afișează DA 3.
Variabila k este de tip întreg, iar variabila s permite memorarea unui șir de maximum 50 de caractere. Indicați valoarea variabilei k în urma executării secvenței alăturate.
strcpy(s,"bac2023");
s[s[2]-'a']='\0';
k=strlen(s);a. 7
b. 6
c. 2
d. 1
Vezi rezolvarea
După strcpy, șirul este "bac2023". Caracterul s[2] este 'c', iar 'c'-'a' .
Atribuirea s[2]='\0' trunchiază șirul la primele două caractere: "ba".
Astfel k=strlen(s) . Răspunsul corect este c.