Cum Gândește Calculatorul? Partea a 8-a: Probleme cu Structuri și Șiruri de Caractere în C/C++

Salut! Astăzi abordăm partea practică de programare: problemele cu structuri, șiruri de caractere și logica de programare. Acestea sunt puncte “sigure” la Bacalaureat dacă le înțelegi bine!

🎯 Strategia Generală pentru Problemele de Programare

  1. Citește cerința de 2 ori – Subliniază datele importante
  2. Identifică tipul de date – Ce variabile sunt necesare?
  3. Gândește algoritmul – Pe hârtie, în română
  4. Scrie codul – Pas cu pas, comentând dacă e necesar
  5. Testează cu exemplul – Mereu verifică cu datele din exemplu

📚 Rezolvări Pas cu Pas

Problema 1: Formatarea Numărului de Telefon

Cerința: Transformă un număr internațional (+254)722123456 cu prefix 0 în număr local 0722123456.

Analiză:

  • Numărul internațional are forma: (cod_țară)număr
  • Trebuie să înlocuim (cod_țară) cu prefixul național (sau șir vid)

Soluție:

#include <cstring>  // pentru funcțiile cu șiruri

// Presupunem că avem:
// char tI[50];  // număr internațional
// char pN[10];  // prefix național
// char tL[50];  // număr local (rezultat)

// Secvența de instrucțiuni:
int i, j;
int parantezaDeschisa = -1, parantezaInchisa = -1;

// 1. Găsim parantezele
for(i = 0; tI[i] != '\0'; i++) {
    if(tI[i] == '(') parantezaDeschisa = i;
    if(tI[i] == ')') parantezaInchisa = i;
}

// 2. Copiem prefixul național (dacă există)
j = 0;
if(strlen(pN) > 0) {
    strcpy(tL, pN);
    j = strlen(pN);
}

// 3. Copiem partea după paranteza închisă (numărul propriu-zis)
if(parantezaInchisa != -1) {
    for(i = parantezaInchisa + 1; tI[i] != '\0'; i++) {
        tL[j] = tI[i];
        j++;
    }
    tL[j] = '\0';  // terminator de șir
}

// Varianta mai simplă cu funcții:
// char tL[50] = "";
// if(strlen(pN) > 0) strcat(tL, pN);
// char* numar = strchr(tI, ')');
// if(numar != NULL) strcat(tL, numar + 1);

Problema 2: Structura Bijuterie

Cerința: Definește structura bijuterie care să permită expresiile b.metal.denumire și b.greutate*b.metal.pret.

Soluție:

struct metal {
    char denumire[31];  // 30 + 1 pentru '\0'
    int pret;           // prețul unui gram
};

struct bijuterie {
    int greutate;       // în grame
    struct metal metal; // metalul prețios
} b;

Explicație:

  • b.metal.denumireb e de tip bijuterie, metal e câmp de tip struct metal, denumire e câmp în metal
  • b.greutate*b.metal.pretgreutate e în bijuterie, pret e în metal care e în bijuterie

Problema 3: Verificare Pătrat

Cerința: Verifică dacă dreptunghiul este pătrat.

Analiză:

  • Avem două puncte: A (stânga-sus) și B (dreapta-jos)
  • Lățime = |B.x – A.x|
  • Înălțime = |A.y – B.y| (atenție la coordonate!)
  • Este pătrat dacă lățime = înălțime și ambele > 0

Soluție:

#include <cmath>  // pentru abs()

struct punct { int x, y; };
struct figura { punct A, B; } d;

// Secvența de instrucțiuni:
int latime = abs(d.B.x - d.A.x);
int inaltime = abs(d.A.y - d.B.y);  // A.y > B.y (sus > jos)

if(latime == inaltime && latime > 0) {
    cout << "DA";
} else {
    cout << "NU";
}

Problema 4: Interval Muzical Terță

Cerința: Verifică dacă două note formează o terță.

Analiză:

  • Notele în engleză: A=la, B=si, C=do, D=re, E=mi, F=fa, G=sol
  • Terța = între note există o singură altă notă
  • Exemplu: G(sol) și B(si) → între ele: la (A) → o notă → este terță

Soluție:

struct interval { char nota1, nota2; } m;

// Mapăm notele la poziții (pentru ordinea din gamă)
// do=C(1), re=D(2), mi=E(3), fa=F(4), sol=G(5), la=A(6), si=B(7)

int pozitie(char nota) {
    switch(nota) {
        case 'C': return 1;
        case 'D': return 2;
        case 'E': return 3;
        case 'F': return 4;
        case 'G': return 5;
        case 'A': return 6;
        case 'B': return 7;
        default: return 0;
    }
}

// Verificare
int p1 = pozitie(m.nota1);
int p2 = pozitie(m.nota2);

if(p1 > 0 && p2 > 0 && abs(p1 - p2) == 2) {
    // Diferența de 2 poziții înseamnă 1 notă între ele
    cout << "TERTA";
} else {
    cout << "NU";
}

Problema 5: Prima Literă sau ‘*’

Cerința: Dacă prețul < 100, primește prima literă a denumirii, altfel ‘*’.

Soluție simplă:

struct produs { char denumire[20]; int pret; } p;
char a;

if(p.pret < 100) {
    a = p.denumire[0];  // prima literă
} else {
    a = '*';
}

Problema 6: Temperatură și Mesaj

Cerința: Afișează mesaj în funcție de temperatură.

Soluție:

struct meteo { int an, temperatura; } x;

if(x.temperatura > 11) {
    cout << "CALDUROS";
} else if(x.temperatura < 10) {
    cout << "RACOROS";
} else {
    cout << "NORMAL";
}

Problema 7: Structura Specialist IT

Cerința: Definește structura pentru expresiile s[5].personal.CNP, s[5].personal.anNastere, s[5].anAngajare.

Soluție:

struct datePersonale {
    char CNP[14];  // 13 caractere + '\0'
    int anNastere;
};

struct specialist {
    struct datePersonale personal;
    int anAngajare;
} s[30];  // vector de 30 de specialiști

Problema 8: Verificare Cuvinte cu 2 Litere

Cerința: Verifică dacă există cuvinte de 2 litere cu o vocală și o consoană.

Soluție:

c = 0;  // inițializare
for(i = 1; i <= 10; i++) {
    cin >> s;

    // Verificăm dacă cuvântul are exact 2 litere
    if(strlen(s) == 2) {
        // Verificăm dacă are o vocală și o consoană
        int esteVocala1 = (s[0]=='a'||s[0]=='e'||s[0]=='i'||s[0]=='o'||s[0]=='u');
        int esteVocala2 = (s[1]=='a'||s[1]=='e'||s[1]=='i'||s[1]=='o'||s[1]=='u');

        // O vocală și o consoană înseamnă că sunt diferite
        if(esteVocala1 != esteVocala2) {
            c = 1;
        }
    }
}

Explicație:

  • c se inițializează cu 0 (presupunem că nu există)
  • Dacă găsim un cuvânt care îndeplinește condiția, setăm c=1
  • esteVocala1 și esteVocala2 sunt 1 pentru vocală, 0 pentru consoană
  • Dacă sunt diferite (!=), avem o vocală și o consoană

🎯 Sfaturi Practice pentru Bacalaureat

  1. Pentru probleme cu șiruri:
  • Nu uita de #include <cstring>
  • Terminatorul de șir '\0' este crucial
  • strlen(s) dă lungimea, strcpy(dest, sursă) copiază, strcat(dest, sursă) adaugă
  1. Pentru structuri:
  • Definește mai întâi structurile interioare
  • Folosește dimensiuni rezonabile (char[30] pentru 29 caractere + ‘\0’)
  • Accesează corect câmpurile: structura.camp sau structura.substructura.camp
  1. Pentru condiții:
  • Folosește paranteze pentru claritate
  • Testează toate cazurile (mai mic, egal, mai mare)
  • Ai grijă la operatori: = este atribuire, == este comparație
  1. Pentru vectori de structuri:
  • s[5] accesează al 6-lea element (indicele începe de la 0!)
  • s[5].personal.CNP accesează câmpul CNP din personal din al 6-lea specialist

💪 Verificare Finală

Încearcă să rezolvi singur următoarea problemă similară:

Problemă: Definește o structură student care să conțină numele (max 30 caractere), media și anul de studiu. Scrie o secvență care să afișeze “BURSA” dacă media este ≥ 9.5, “EXAMEN” dacă media este între 5 și 9.5, altfel “CORIGENT”.

Soluție rapidă:

struct student { char nume[31]; float media; int an; } s;

if(s.media >= 9.5) cout << "BURSA";
else if(s.media >= 5) cout << "EXAMEN";
else cout << "CORIGENT";

✨ Motivare Finală

Uite cât de multe ai învățat! De la probleme simple până la structuri complexe. Fiecare problemă rezolvată te apropie mai mult de succesul la Bacalaureat.

Cel mai important: Nu te grăbi! Citește atent, gândește pe hârtie, testează codul mental. La examen vei avea timp suficient dacă ești organizat.

Ai devenit un adevărat programator! 🚀

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *