Școala Româno-Britanică
Modulul 2 Clasa a X-a | C++

Ora 5: Căutarea unui caracter sau subșir

Ce vei învăța astăzi: Cum căutăm un caracter într-un șir cu strchr (funcție care caută un caracter într-un șir), un subșir (o succesiune de caractere aflată în interiorul altui șir, de exemplu „car" în „caracter") cu strstr (funcție care caută un subșir într-un text) și cum facem căutarea manual

Rezultat practic: Scrii programe C++ care caută un caracter sau un subșir într-un text, folosind funcțiile standard sau căutarea manuală cu for (Competența 3.2).

Competența 3.2 Săptămâna 7

Înainte de a începe

De ce contează? Căutarea stă la baza aplicațiilor de text: verificatoare ortografice, motoare de căutare, validarea parolelor — toate verifică dacă un anumit caracter sau șir apare în altul, exact ca strchr și strstr.

Ce știi deja?

La ora 4 ai copiat și lipit șiruri cu strcpy și strcat. Cum ai număra aparițiile literei 'a' în cuvântul „matematica" folosind o parcurgere cu for? Ce condiție ai verifica pentru fiecare caracter?

Ideea-cheie: strchr(s, c) caută prima apariție a caracterului c, iar strstr(s, sub) prima apariție a subșirului; ambele întorc NULL când nu găsesc nimic, iar poziția primei apariții se află făcând diferența dintre pointerul întors (o adresă de memorie care indică locul unde a fost găsit) și începutul șirului.
SINTEZĂ TEORETICĂ ȘI EXEMPLE GHIDATE

Ce vei învăța astăzi?

După această lecție vei ști să cauți un caracter într-un șir, să cauți un subșir (un grup de caractere) și să numeri aparițiile unui caracter printr-o căutare manuală.

Căutarea cu strchr
Căutarea cu strstr
Căutarea manuală
Numărarea aparițiilor

Căutarea unui caracter cu strchr

Definiție: strchr(s, c) returnează un pointer către prima apariție a caracterului c în șirul s. Dacă caracterul nu apare, returnează NULL. Poziția caracterului se calculează cu p - s.

Analogia: căutarea unei pagini la carte

Dacă un prieten îți spune „caută prima pagină pe care apare cuvântul tău", tu întorci paginile până găsești prima apariție. Dacă nu există, îi răspunzi că nu s-a găsit. Exact asta face strchr, dar pentru caractere.

Algoritm căutareCaracter citește s, c (caracterul căutat) p = strchr(s, c) dacă p nu este NULL atunci poz = p - s scrie "Caracterul se află pe poziția ", poz altfel scrie "Caracterul nu a fost găsit" sfârșit dacă Sfârșit algoritm
C++ - căutarea unui caracter
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    cin.getline(s, 101);

    char *p = strchr(s, 'a');

    if (p == NULL)
    {
        cout << "Caracterul 'a' nu apare in sir";
    }
    else
    {
        cout << "Prima aparitie a caracterului 'a' este la pozitia "
             << p - s;
    }

    return 0;
}

Ce învățăm: p - s este diferența dintre două adrese din memorie și dă exact poziția (începând de la 0) a caracterului găsit.

Căutarea unui subșir cu strstr

Definiție: strstr(s, sub) caută șirul sub în interiorul șirului s și returnează un pointer către prima apariție, sau NULL dacă subșirul nu există.

Exemplu ghidat: conține textul cuvântul „BAC"?

C++ - căutarea unui subșir
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101], sub[101];

    cin.getline(s, 101);
    cin.getline(sub, 101);

    char *p = strstr(s, sub);

    if (p == NULL)
    {
        cout << "Subsirul nu apare in text";
    }
    else
    {
        cout << "Subsirul incepe la pozitia " << p - s;
    }

    return 0;
}

Observă: pentru textul elevul a luat bac și subșirul bac, se afișează poziția 15.

Căutarea manuală: numărarea aparițiilor

Prin căutare manuală parcurgem șirul caracter cu caracter și comparăm fiecare caracter cu cel căutat. Astfel putem număra toate aparițiile, nu doar prima.

C++ - de câte ori apare un caracter?
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    char c;

    cin.getline(s, 101);
    cin >> c;

    int contor = 0;

    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] == c)
        {
            contor++;
        }
    }

    cout << "Caracterul " << c << " apare de " << contor << " ori";

    return 0;
}

Ce învățăm: căutarea manuală cu for + contor este metoda sigură la BAC pentru orice problemă de numărare.

Exercițiu de completare

Completează enunțul despre căutare:

Funcția ______ caută un caracter într-un șir, iar ______ caută un subșir. Ambele returnează un ______ către prima apariție; dacă nu găsesc nimic, returnează ______.

Bancă de cuvinte:
strchr strstr pointer NULL

Exercițiu de completare a codului

Completează programul care găsește poziția primei apariții:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    char s[101];
    cin.getline(s, 101);
    char *p = ______(s, 'e');
    if (p == ______)
    {
        cout << "Nu apare";
    }
    else
    {
        cout << p - ______;
    }
    return 0;
}
Bancă de cuvinte:
strchr NULL s

Test de înțelegere

Test rapid - căutarea în șiruri:

1. Ce returnează strchr(s, 'a') dacă 'a' nu există în s?

2. Cum se calculează poziția caracterului găsit?

3. Ce caută strstr(s, sub)?

Ai grijă la: poziția primului caracter găsit de strchr se calculează cu p - s, nu cu p + s; iar dacă funcția întoarce NULL, orice folosire a pointerului întors este greșită. Verifică întotdeauna pointerul înainte de a-l folosi.

Aprofundare

Cazuri particulare și detalii avansate:

  • strchr returnează un pointer, nu o poziție. Pentru a afla poziția folosim diferența de pointeri: poz = p - s. Dacă caracterul nu există, returnează NULL; verificarea p != NULL este obligatorie.
  • Căutarea manuală cu for: parcurgem șirul și ne oprim la prima poziție i cu s[i] == c. Un indicator gasit (boolean) ne ajută să afișăm rezultatul corect la final.
  • Numărarea aparițiilor continuă parcurgerea până la capăt, incrementând un contor de fiecare dată când s[i] == c.
  • strstr(s, sub) caută un subșir întreg, nu un singur caracter; și el returnează pointer către prima apariție sau NULL.
  • Mai multe apariții: pentru a găsi toate pozițiile unui caracter, parcurgem întregul șir cu for și testăm fiecare caracter în parte.

Căutarea răspunde la întrebarea „apare caracterul X în șir și, dacă da, unde?" — aceeași idee stă la baza căutării unui cuvânt într-un text și a verificării dacă un subșir se află în altul.

APLICARE ȘI REZOLVARE DE PROBLEME

PbInfo - Căutarea unui caracter

Enunț:

Cerință: Se citesc un șir s și un caracter c. Să se afișeze poziția primei apariții a caracterului c (pozițiile încep de la 0) sau -1 dacă caracterul nu apare.

Date de intrare:

Programul citește de la tastatură șirul s, apoi caracterul c.

Date de ieșire:

Programul va afișa poziția primei apariții sau -1.

Restricții și precizări:

Șirul are cel mult 100 de caractere și conține doar litere mici.

Exemplu:

Intrare:

bacalaureat
l

Ieșire:

4
Cum gândim soluția:
  1. Citim șirul cu cin.getline și caracterul cu cin
  2. Parcurgem șirul cu for și ne oprim la prima potrivire cu break
  3. Afișăm poziția sau -1 dacă nu am găsit
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    char c;

    cin.getline(s, 101);
    cin >> c;

    int poz = -1;

    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] == c)
        {
            poz = i;
            break;
        }
    }

    cout << poz;

    return 0;
}

Ce învățăm: inițializăm poziția cu -1 („nu am găsit") și o actualizăm la prima potrivire, apoi ieșim cu break.

PbInfo - Câte litere a are

Enunț:

Cerință: Se citește un text format doar din litere mici. Să se afișeze de câte ori apare litera a în text.

Date de intrare:

Programul citește de la tastatură textul.

Date de ieșire:

Programul va afișa un număr reprezentând numărul de apariții ale literei a.

Restricții și precizări:

Textul are cel mult 100 de caractere și conține doar litere mici, fără spații.

Exemplu:

Intrare:

banana

Ieșire:

3
Cum gândim soluția:
  1. Citim textul cu cin.getline
  2. Parcurgem fiecare caracter și, dacă este 'a', incrementăm contorul
  3. Afișăm contorul
Scrie soluția în C++:
Soluție corectă:
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    cin.getline(s, 101);

    int contor = 0;

    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] == 'a')
        {
            contor++;
        }
    }

    cout << contor;

    return 0;
}

Ce învățăm: numărarea tuturor aparițiilor se face prin căutare manuală completă, nu cu strchr (care găsește doar prima apariție).

EXERCIȚII PRACTICE

Exercițiul Practic: căutarea în șiruri

Sarcini de lucru

Completează următoarele sarcini pentru a exersa căutarea de caractere și subșiruri

Sarcina 1: Conține subșirul BAC?

Cerință: Scrie un program C++ complet care citește un text și afișează DA dacă textul conține subșirul bac, altfel NU, folosind strstr.

Soluție pentru Sarcina 1:
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    cin.getline(s, 101);

    if (strstr(s, "bac") != NULL)
    {
        cout << "DA";
    }
    else
    {
        cout << "NU";
    }

    return 0;
}

Verifică: pentru intrarea examenul de bac, programul afișează DA.

Sarcina 2: Câte e-uri are textul?

Cerință: Scrie un program C++ complet care citește un text cu litere mici și afișează de câte ori apare litera e. Pentru intrarea elevul evalueaza se afișează 3 (e, e, e).

Soluție pentru Sarcina 2:
#include <iostream>
#include <cstring>
using namespace std;

int main()
{
    char s[101];
    cin.getline(s, 101);

    int contor = 0;

    for (int i = 0; i < strlen(s); i++)
    {
        if (s[i] == 'e')
        {
            contor++;
        }
    }

    cout << contor;

    return 0;
}

Verifică: în elevul evalueaza literele e apar pe pozițiile 0, 6 și 14, deci contorul ajunge la 3.

Scrie pe caiet - De reținut

Titlul lecției

Ora 5: Căutarea unui caracter sau subșir

Definiția lecției

Căutarea răspunde la întrebarea: apare caracterul sau subșirul căutat în text și, dacă da, pe ce poziție? Funcția strchr caută un singur caracter și întoarce un pointer către prima apariție, iar strstr caută un subșir întreg. Ambele funcții întorc NULL atunci când nu găsesc nimic, deci verificarea rezultatului este obligatorie. Poziția primei apariții se calculează făcând diferența dintre pointerul întors și începutul șirului. Căutarea manuală parcurge șirul cu for, caracter cu caracter, până la o potrivire sau până la sfârșit. Căutarea stă la baza verificării parolelor, a motoarelor de căutare și a analizei textelor.

Definiții esențiale

Algoritmul cheie - pseudocod

Algoritm căutareCaracter citește s, c p = strchr(s, c) dacă p nu este NULL atunci poz = p - s scrie "Caracterul se află pe poziția ", poz altfel scrie "Caracterul nu a fost găsit" sfârșit dacă Sfârșit algoritm

Algoritmul cheie - cod C++

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

int main()
{
    char s[101];
    char c;
    cin.getline(s, 101);
    cin >> c;

    char *p = strchr(s, c);

    if (p != NULL)
    {
        int poz = p - s;
        cout << "Caracterul se afla pe pozitia " << poz << endl;
    }
    else
    {
        cout << "Caracterul nu a fost gasit" << endl;
    }

    return 0;
}

Greșeli comune de evitat

Sfaturi practice și trucuri

Exemplu practic

Scrie un program care citește un text și verifică dacă acesta conține subșirul bac. Pentru textul elevul a luat bac, programul afișează: DA, subșirul a fost găsit pe poziția 15.

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

int main()
{
    char s[101];
    cin.getline(s, 101);

    char *p = strstr(s, "bac");

    if (p != NULL)
    {
        cout << "DA, gasit pe pozitia " << p - s << endl;
    }
    else
    {
        cout << "NU" << endl;
    }

    return 0;
}