Prelucrarea cifrelor unui număr
Cum descompui un număr în cifre, cum îl reconstruiești și tiparele care apar în aproape orice subiect de la II și III.
Cele două operații
Tot ce urmează se sprijină pe două operații:
n % 10 // ultima cifră
n / 10 // numărul fără ultima cifrăPentru n = 4071: n % 10 este 1, n / 10 este 407. Dacă repeți, ajungi la toate cifrele, de la dreapta la stânga.
Parcurgerea cifrelor
Acesta este tiparul de bază și îl vei scrie de sute de ori:
while (n > 0) {
int c = n % 10;
// aici prelucrez cifra c
n /= 10;
}Ai grijă la trei lucruri.
Bucla distruge pe n. După ea, n este 0. Dacă mai ai nevoie de valoarea inițială, salveaz-o înainte într-o copie.
Pentru n = 0 bucla nu se execută deloc. Dacă problema cere „numărul de cifre", pentru 0 răspunsul corect este 1, dar bucla dă 0. Cazul zero îl tratezi separat.
Condiția este n > 0, nu n != 0. Pentru numere negative, n > 0 oprește bucla imediat. Dacă enunțul permite numere negative, lucrează cu valoarea absolută.
Ce se calculează așa
Suma cifrelor
int s = 0;
while (n > 0) {
s += n % 10;
n /= 10;
}Numărul de cifre
int cate = 0;
while (n > 0) {
cate++;
n /= 10;
}
if (cate == 0) cate = 1; // cazul n = 0Cea mai mare cifră
int maxim = 0;
while (n > 0) {
int c = n % 10;
if (c > maxim) maxim = c;
n /= 10;
}Aici poți inițializa liniștit cu 0, pentru că nicio cifră nu e mai mică decât 0. Pentru cea mai mică cifră inițializează cu 9, nu cu 0. Altfel răspunsul iese mereu 0.
Câte cifre pare are
int cate = 0;
while (n > 0) {
if ((n % 10) % 2 == 0) cate++;
n /= 10;
}Construirea unui număr din cifre
Aici faci invers: pornești de la 0 și adaugi cifre la sfârșit.
rezultat = rezultat * 10 + cifra;Înmulțirea cu 10 mută tot ce aveai cu o poziție spre stânga, iar adunarea pune noua cifră pe ultima poziție.
Răsturnatul unui număr
int rasturnat = 0;
while (n > 0) {
rasturnat = rasturnat * 10 + n % 10;
n /= 10;
}Pentru n = 4071 obții 1704. Observă că zerourile de la sfârșitul numărului inițial dispar: răsturnatul lui 500 este 5, nu 005.
Numărul format doar din cifrele impare
Aici apare o problemă. Când parcurgi de la dreapta la stânga, cifrele ies în ordine inversă, iar dacă le adaugi la sfârșit obții numărul răsturnat.
Soluția este să construiești numărul cu o putere a lui 10 care crește:
int rezultat = 0, p = 1;
while (n > 0) {
int c = n % 10;
if (c % 2 == 1) {
rezultat = rezultat + c * p;
p *= 10;
}
n /= 10;
}p este 1 la prima cifră păstrată, 10 la a doua, 100 la a treia. Așa cifrele rămân în ordinea din numărul inițial.
Pentru n = 4071, cifrele se parcurg în ordinea 1, 7, 0, 4. Cele impare sunt 1 și 7, iar rezultatul este 71.
Când nicio cifră nu se potrivește, rezultatul rămâne 0. Verifică dacă enunțul cere altceva în acest caz.
Palindrom
Un număr este palindrom dacă este egal cu răsturnatul său.
int copie = n, rasturnat = 0;
while (copie > 0) {
rasturnat = rasturnat * 10 + copie % 10;
copie /= 10;
}
if (rasturnat == n) cout << "DA";
else cout << "NU";Aici vezi de ce ai nevoie de copie: la final compari cu n original, deci n nu are voie să fie distrus.
Cifrele în ordinea firească
Dacă chiar ai nevoie de cifre de la stânga la dreapta, ai două variante.
Răstoarnă întâi numărul, apoi parcurge-l normal. E simplu, dar pierzi zerourile de la sfârșit.
Calculează puterea lui 10 potrivită:
int p = 1;
int copie = n;
while (copie > 9) { p *= 10; copie /= 10; }
while (p > 0) {
int c = n / p % 10; // cifra curentă
// prelucrez c
p /= 10;
}A doua variantă este mai sigură. Totuși, în majoritatea problemelor ordinea nu contează, așa că verifică enunțul înainte să complici codul.
De reținut
n % 10ia ultima cifră,n / 10o taie. De aici pornește totul.- Bucla distruge
n, deci salvează o copie dacă mai ai nevoie de valoare. n = 0este mereu un caz special: bucla nu pornește.- Construiești un număr cu
r = r * 10 + c. Ca să păstrezi ordinea, folosește o puterepcare crește. - Pentru cea mai mică cifră inițializează cu 9, nu cu 0.