Universidad de Costa Rica
Escuela de Ciencias de la
Computación e Informática
Profesor Adolfo Di Mare
CI-1101
II Semestre 2000
[<=] [home] [<>] [\/] [=>]
CI-1101 Programación I

Examen #1 [solución]

      Duración: dos horas. Lea bien el examen antes de hacerlo. El examen es a libro abierto. Cuenta la documentación. Cuenta la redacción y la ortografía. Puede hacer el examen con lápiz. Resuelva tres de las cuatro preguntas. ¡No haga más de lo que se le pide!

 

1) [33 pts]

#include <iostream>
#include <iomanip>
#include <bool.h>

int main() {
    int ln = 0;
    for (int i = (5 % 4); i <= (777 / 11); ++i) {
        for (int j = (30 % 333); j <= (333 / 11); ++j) {
            bool w = false;
            if ((i % 7) == 3) {
                w = true;
            }
            else if (j % 5 == 0) {
                w = true;
            }
            if (w) {
                cout << "  ==> " << setw(2) << i;
                ++ln;
                if (ln==3) {
                    cout << endl;
                    ln = 0;
                }
            }
        }
    }
    return 0;
}
Figura 1

1.a) [9 pts] En la Figura 1, indique cuál es el rango que recorren las variables "i" y "j".

1.b) [15 pts] Muestre cuál es el resultado de ejecutar este programa. Trate de ser conciso en su respuesta.

1.c) [9 pts] Explique para qué sirve la variable "ln".

 

2) [33 pts] Un número romano está formado por una secuencia formada con las letras M-D-C-L-X-V-I. Cada letra tiene un valor diferente, desde 1.000 hasta 1. La regla para traducir un número romano a un número entero es muy simple: se suma el valor de cada carácter romano, excepto cuando ocurre que el siguiente carácter romano es mayor, en cuyo caso lo que se suma es la diferencia entre los dos:

M = 1.000     VI       ==> 6        (5+1)
D =   500     IX       ==> 9        (10-1)
C =   100     LXXXVII  ==> 87       (50+10+10+10+5+1+1)
L =    50     CCXIX    ==> 219      (100+100+10+(10-1))
X =    10     MCCCLIV  ==> 1354     (1000+100+100+100+50+(5-1))
V =     5     MCMLVI   ==> 1956     (1000+(1000-100)+50+5+1)
I =     1                              M      CM      L V I   
Figura 1

2.a) [13 pts] Especifique la función Romano_INT() que sirve para leer, letra por letra, un número romano (la lectura termina cuando se lee un espacio en blanco). Su especificación debe quedar bien completa.

2.b) [20 pts] Implemente Romano_INT() (SUGERENCIA: use dos variables, para saber cuál es el carácter anterior y cuál es el actual; también puede usar una función que retorne el valor de cada letra, de acuerdo a la Figura 1).

 

3) [33 pts] El problema del año dos mil (Y2K) surge cuando en un programa hay que restar dos fechas escritas con dos dígitos, pues el resultado puede ser un número negativo. Por ejemplo, 10-99 debe interpretarse como 2010-1999, que debe dar por resultado el número 11. Sin embargo, el resultado aritmético es incorrecto: -89 = 10-99.

class y2k {
private:
    char d,u; // decenas + unidades
public:
    enum { Corte = 60 }; // año de corte

    y2k()      : u(0),      d(0)              {}
    y2k(int y) : u(y % 10), d( (y % 100)/10 ) {}

    int Resta(/*...*/);
}; // y2k
Figura 3

      Al escribir su algoritmo usted debe completar la fecha contenida en una instancia de la clase y2k, anteponiendo los dígitos 19 para los años 1900, o 20 para los años 2000. La constante y2k::Corte es el año a partir del cual en su clase se antepone a la pareja de dígitos 19, y para los años anteriores se antepone 20. Por ejemplo, si el valor y2k::Corte es 60, el valor 60 representa el año 1960, el 61 representa 1961, pero el valor 59 representa el año 2059 y 00 representa el año 2000.

3.a) [13 pts] Especifique el método y2k::Resta(). No olvide definir los parámetros.

3.b) [20 pts] Implemente y2k::Resta(). En su implementación use la declaración de la clase y2k que está en la Figura 3.

 

4) [33 pts] Considere esta implementación del operador >> para la clase racional que usted utilizó en la Tarea #6.

istream& operator >> (istream &s, racional& r) {
/*  resultado
    Lee del flujo de texto "s" el valor de "r". */
/*  requiere
    El número racional debe haber sido escrito usando
    el formato "[r/den]", aunque es permisible usar
    algunos blancos.
    - Se termina de leer el valor al encontrar "]".
    - [ -+-+-+-+- 4 / -- -+ -- 32  ] se lee como [1/8].
*/
    char ch;  // valor leído, letra por letra, de "s"

    // se brinca todo hasta el primer dígito
    do {
        s >> ch;
    } while (!isdigit(ch));

    // se traga el numerador
    r._num = 0;
    while (isdigit(ch)) {
        r._num = 10 * r._num + (ch-'0');
        s >> ch;
    }

    // lee el denominador si no encuentra carácter de fin "]".
    r._den = 1;
    if (ch != ']') { // se brinca todo hasta el denominador
       do {
           s >> ch;
        } while (!isdigit(ch));

        r._den = 0;
        while (isdigit(ch)) {
            r._den = 10 * r._den + (ch-'0');
            s >> ch;
        }

        // Si el usuario no pone el carácter delimitador final "]"
        // el programa se pega, pues para hasta que lo encuentre.
        while (ch!=']') {
            s >> ch;
        }
    }  // corrección: Andrés Arias <e980300@anubis.ecci.ucr.ac.cr>

    r.simplifique();
    return s;
}  // operator >>
Figura 4

4.a) [8 pts] Dé un ejemplo en que este operador no funciona correctamente. Explique cuál es el problema.

4.a) [25 pts] Corrija esta implementación.

Soluciones

[mailto:] Adolfo Di Mare <adolfo@di-mare.com>.
Copyright © 2000
Derechos de autor reservados © 2000
[home] <> [/\]