Lecție pentru bacalaureat · Informatică

Șiruri de caractere

Clasa a X-a

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

Formulă

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);
Sfat

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.

Formulă

Ș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, negat
Sfat

Capcana: - 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ă.

Formulă

Ș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

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.

Formulă

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 subsirul
Sfat

Capcana: 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.

Formulă

Ș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;
Formulă

Ș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 2⋅k2 \cdot k (k∈[1,102]k \in [1,10^2]) litere, prin interschimbarea în acesta a secvenței formate din primele kk litere cu secvența formată din ultimele kk 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ă 2k2k, 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' =2= 2.

Atribuirea s[2]='\0' trunchiază șirul la primele două caractere: "ba".

Astfel k=strlen(s) =2= 2. Răspunsul corect este c.

Toate lecțiile de Informatică

Descarcă

Începe azi. Bacul nu așteaptă.

Descarcă Tomomi pe telefonul copilului tău și pornește perioada de probă gratuită.