Dacă te uiți la subiectele de BAC informatică din ultimii ani, vei vedea că foarte mulți algoritmi din pseudocod (Subiectul II) și multe subprograme cerute la Subiectul III prelucrează cifrele unui număr natural: le adună, le numără, le inversează, păstrează doar o parte din ele. Toate aceste probleme folosesc aceeași idee de bază, cu % 10 și / 10.
Șablonul de bază: extragerea cifrelor
Pentru un număr natural n, n % 10 este ultima cifră, iar n / 10 este numărul rămas după ce o tăiem. Repetând aceste două operații cât timp n mai are cifre, le parcurgem pe toate, de la dreapta la stânga:
while (n > 0)
{
int c = n % 10; // cifra curentă
// ... prelucrezi cifra c ...
n = n / 10; // tai ultima cifră
}
În pseudocod, același șablon arată așa:
cât timp n>0 execută
c ← n%10
...
n ← [n/10]
Două observații care contează. Prima: cifrele se obțin în ordine inversă, de la unități spre prima cifră. A doua: bucla distruge valoarea lui n. Dacă mai ai nevoie de numărul inițial (de exemplu pentru palindrom), păstrează o copie înainte.
Suma, produsul și numărul cifrelor
Toate trei sunt variații directe ale șablonului:
int sumaCifre(int n)
{
int s = 0;
while (n > 0)
{
s = s + n % 10;
n = n / 10;
}
return s;
}
Pentru număr de cifre înlocuiești s = s + n % 10 cu k++, iar pentru produs pornești de la p = 1 și înmulțești. Pentru n = 4728, suma cifrelor este 4 + 7 + 2 + 8 = 21, iar numărul de cifre este 4.
Capcana lui zero. Pentru n = 0, bucla while nu se execută deloc, deci numărul de cifre iese 0, deși 0 are o cifră. Dacă enunțul permite n = 0, folosește do … while (în pseudocod: repetă … până când n=0), care execută corpul cel puțin o dată.
Cifra maximă și cifre cu o proprietate
Pentru cifra maximă pornești cu maxim = 0 (nicio cifră nu e mai mică de 0) și compari fiecare cifră. Pentru „câte cifre pare are numărul” adaugi un if (c % 2 == 0) în corpul buclei. Aceeași structură rezolvă „suma cifrelor impare”, „câte cifre sunt egale cu prima cifră” (după ce afli prima cifră) sau „există o cifră egală cu k”.
Oglinditul unui număr
Oglinditul (inversul) lui 4728 este 8274. Ideea: construim un număr nou, adăugând la dreapta lui, pe rând, cifrele extrase. A „adăuga o cifră la dreapta” înseamnă a înmulți cu 10 și a aduna cifra.
int oglindit(int n)
{
int r = 0;
while (n > 0)
{
r = r * 10 + n % 10;
n = n / 10;
}
return r;
}
Urmărirea pentru n = 4728:
| Pas | n % 10 | r | n după pas |
|---|---|---|---|
| 1 | 8 | 0·10 + 8 = 8 | 472 |
| 2 | 2 | 8·10 + 2 = 82 | 47 |
| 3 | 7 | 82·10 + 7 = 827 | 4 |
| 4 | 4 | 827·10 + 4 = 8274 | 0 |
Atenție la zerourile de la final: oglinditul lui 1200 este 21, nu 0021. Un număr natural nu poate începe cu zerouri.
Palindromul
Un număr este palindrom dacă se citește la fel de la stânga la dreapta și invers, adică este egal cu oglinditul său: 12321, 7, 4554. Pentru că bucla strică n, compari oglinditul cu o copie:
bool palindrom(int n)
{
return oglindit(n) == n;
}
Aici funcția oglindit primește o copie a lui n (transmitere prin valoare), deci n din palindrom rămâne nemodificat. Pentru 1200, oglinditul 21 este diferit de 1200, deci nu e palindrom — exact cum trebuie.
Construirea unui număr din anumite cifre, în ordinea inițială
O cerință foarte frecventă: „obține numărul format din cifrele impare ale lui n, în ordinea în care apar”. Dacă ai construi ca la oglindit, ordinea s-ar inversa. Soluția: pui fiecare cifră păstrată în fața rezultatului, folosind o putere a lui 10.
int cifreImpare(int n)
{
int r = 0, p = 1;
while (n > 0)
{
int c = n % 10;
if (c % 2 == 1)
{
r = c * p + r;
p = p * 10;
}
n = n / 10;
}
return r;
}
Pentru n = 4735: cifra 5 dă r = 5, p = 10; cifra 3 dă r = 30 + 5 = 35, p = 100; cifra 7 dă r = 700 + 35 = 735, p = 1000; cifra 4 este pară și se sare. Rezultat: 735. Dacă nicio cifră nu e impară, funcția întoarce 0 — verifică ce cere enunțul în acest caz (de obicei un mesaj sau valoarea -1).
Același tipar rezolvă „elimină toate cifrele egale cu k” (păstrezi cifrele diferite de k) sau „dublează fiecare cifră pară” (pentru o cifră dublată o adaugi de două ori, înmulțind p cu 10 după fiecare adăugare).
Un program complet
Programul de mai jos citește un număr natural și afișează suma cifrelor, oglinditul și dacă este palindrom:
#include <iostream>
using namespace std;
int oglindit(int n)
{
int r = 0;
while (n > 0)
{
r = r * 10 + n % 10;
n = n / 10;
}
return r;
}
int main()
{
int n, s = 0;
cin >> n; // de exemplu 12321
int copie = n;
while (copie > 0)
{
s = s + copie % 10;
copie = copie / 10;
}
cout << s << "\n"; // 9
cout << oglindit(n) << "\n"; // 12321
if (oglindit(n) == n)
cout << "palindrom";
else
cout << "nu este palindrom";
return 0;
}
De reținut
- ● Șablonul:
c = n % 10, prelucrezic,n = n / 10, cât timpn > 0. - ● Cifrele ies de la dreapta la stânga, iar
nse distruge; păstrează o copie dacă îți trebuie. - ● Pentru
n = 0foloseștedo … whiledacă trebuie numărată cifra 0. - ● Oglindit:
r = r * 10 + c. Ordine păstrată:r = c * p + r, cupputere a lui 10. - ● Palindrom înseamnă număr egal cu oglinditul său.