Aplicació: Suma d’un segon
Aquest lliçó reforça l’ús de la instrucció condicional amb un programa que afegeix un segon a una hora del dia, donades les seves hores, minuts i segons.
Descripció del problema
Considereu el problema següent: Donada un hora (amb el seu nombre
d’hores, de minuts i de segons), es vol sumar un segon a aquesta hora.
A més, es vol que el resultat s’escrigui amb el format habitual
dels rellotges: les hores, minuts i segons s’escriuen amb dos dígits
i se separen per dos punts. Per exemple, donada l’hora 14:09:59
,
cal escriure 14:10:00
.
Entrada
L’entrada consisteix en tres naturals h
, m
i s
que representen una hora
del dia, és a dir, tals que 0 <= h
< 24, 0 <= m
< 60, i 0 <= s
< 60.
Sortida
Cal escriure el nou temps definit per h, m i s més un segon,
en el format HH:MM:SS
.
Exemples
- Per a l’entrada
10 20 30
cal escriure10:20:31
. - Per a l’entrada
0 0 59
cal escriure00:01:00
. - Per a l’entrada
23 59 59
cal escriure00:00:00
.
Solució
Per resoldre el problema, dividirem el programa en tres passos:
- Primer, es llegiran les dades de l’entrada (una hora del dia).
- Després, se sumarà un segon a aquesta hora del dia.
- Finalment, s’escriurà l’hora del dia resultant, en el format requerit.
És molt habitual dividir un programa en aquests tres passos (lectura, càlcul i escriptura). A continuació els detallem:
1. Lectura de l’hora
Tal com diu l’enunciat, l’entrada consisteix en tres naturals h
, m
i s
que
representen una hora del dia. Per tant, les declarem com a variables de tipus enter (int
):
int h, m, s;
La lectura és ben senzilla: només cal llegir les tres dades, l’una darrera l’altra:
cin >> h >> m >> s;
Recordeu que aquesta instrucció llegeix tres enters del canal d’entrada
(cin
) i els deixa en ordre en h
, m
i s
respectivament.
2. Increment d’un segon
Per sumar un segon a l’hora,
cal sumar un a la variable s
, que representa el nombre de segons.
Com ho farem?
Amb la instrucció
s = s + 1;
Per exemple, suposem que s
val 23 abans d’executar aquesta línia.
Primer, es calcula el valor de s + 1
, el qual és 24.
Després, aquest valor es copia a s
.
Realment, l’efecte final és un increment d’s
,
en aquest cas de 23 a 24.
Ara, si el nombre resultant és menor que 60, ja hem acabat.
Altrament, el nombre de segons és exactament 60 (perquè sabem per
l’enunciat que estava entre 0 i 59),
i per tant cal posar a zero el nombre de segons s
i sumar un a la variable m
, que representa el nombre de minuts.
Si el nombre resultant és menor que 60, ja hem acabat també.
Sinó, caldrà posar a zero el nombre de minuts m
i sumar un a la variable h
, que representa el nombre d’hores.
Finalment, si el nombre d’hores resultat és 24,
cal posar h
a zero, perquè les
24:00:00
no és una hora vàlida: hauria de ser 00:00:00
.
Tot aquest procés el podem implementar de la forma següent amb condicionals imbricats:
s = s + 1;
if (s == 60) {
s = 0;
m = m + 1;
if (m == 60) {
m = 0;
h = h + 1;
if (h == 24) h = 0;
}
}
En aquest programa, les frases com ara
“Si el nombre resultant és menor que 60, ja hem acabat.
Altrament, …“ han estat codificades del revés: if (s == 60) { ... }
.
D’aquesta forma ens estalviem construccions amb cossos buits.
Recordeu que l’operador de comparació s’escriu amb dos iguals
(==
) i que la instrucció d’assignació utilitza un sol igual (=
). Per
això, quan es comprova si h
ha arribat a 24 s’utilitza la condició h == 24
,
però quan es posa el seu valor a zero s’utilitza la instrucció h = 0;
.
A més, fixeu-vos que, en informàtica, l’operador d’assignació =
(llegit pren per valor)
indica que el valor expressat a la dreta s’ha de desar a la variable
de l’esquerra. En matemàtiques, s = s + 1
seria una absurditat.
3. Escriptura del resultat
Un cop incrementada l’hora d’entrada en un segon,
toca escriure el resultat:
Primer, cal escriure h
, m
i s
separades per :
.
A més, cal assegurar que cada nombre s’escrigui amb dos dígits.
Com aconseguir-ho?
Doncs escrivint un zero abans si el seu valor no arriba a deu.
Així doncs, podem escriure la part corresponent a l’hora d’aquesta forma:
if (h < 10) cout << 0;
cout << h << ":";
i completar-ho de la mateixa forma per la part dels minuts i dels segons:
if (m < 10) cout << 0;
cout << m << ":";
if (s < 10) cout << 0;
cout << s << endl;
- Observeu que en lloc d’escriure el caràcter de dos punts després d’
s
, cal escriureendl
per posar el salt de línia final.
Solució completa
El programa complet queda doncs així:
#include <iostream>
using namespace std;
int main() {
// 1. Lectura de l'hora
int h, m, s;
cin >> h >> m >> s;
// 2. Increment d'un segon
s = s + 1;
if (s == 60) {
s = 0;
m = m + 1;
if (m == 60) {
m = 0;
h = h + 1;
if (h == 24) {
h = 0;
}
}
}
// 3. Escriptura del resultat
if (h < 10) cout << 0;
cout << h << ":";
if (m < 10) cout << 0;
cout << m << ":";
if (s < 10) cout << 0;
cout << s << endl;
}
Solució alternativa
Per resoldre aquest problema, també ens podem inspirar en el programa de la descomposició horària. La part del càlcul del resultat quedaria així:
// 2. Increment d'un segon
int t = 3600*h + 60*m + s + 1; // Nombre total de segons
if (t == 3600*24) t = 0; // Per evitar el 24:00:00
int h = n/3600; // Càlcul del nombre d'hores
int m = (n%3600)/60; // Càlcul del nombre de minuts
int s = n%60; // Càlcul del nombre de segons
}
Lliçons.jutge.org
Jordi Petit, Salvador Roura
Universitat Politècnica de Catalunya, 2023
Prohibit copiar. Tots els drets reservats.
No copy allowed. All rights reserved.