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

Tarea #3 [solución]

Clase rotadora de hileras

      Cuando se trabaja con hileras usualmente lo más simple es utilizar la clase std::string<> de la biblioteca STL de C++. Pero si se necesita una funcionalidad diferente no queda más que usar otra clase.

      Como ocurre con la clase string<>, la clase rotador contiene una secuenca de letras, pero incluye el método rotador::rotar(int i) para rotar el valor contenido en la hilera. Por ejemplo, si la hilera contenida es "0123abc", al rotarla i==4 posiciones hacia la izquierda [←] quedaría convertida en "abc0123", que es lo mismo que ocurre si se rota hacia la derecha [→] i==3 posiciones (un valor negativo para el argumento i produce una rotación izquierda, y uno positivo produce una rotación derecha) . Otra forma de lograr la misma rotación es definir cuál es la posición que pasará a ser la primera letra de la hilera después de rotar: por ejemplo, si se usa rotador::dePrimero(unsigned i) con un valor de i==4 para la hilera "0123abc", esta quedará convertida en "abc0123" porque en la hilera original la letra que está en la cuarta posición es 'a'. Es válido usar cualquier número entero como argumento para el método rotar(int i), pero para dePrimero(unsigned i) el argumento debe ser un número positivo en el rango [0..size()-1].

      Hay muchas maneras de implementar la clase rotador, pero la más simple es almancer en el Rep una hilera con la anotación de cuál es la primera letra. Por ejemplo, internamente estaría almancenada la hilera "0123abc" con posición de inicio 4, lo que indicaría que el valor almacenado es "abc0123". En este caso, al utilizar el método rotador::at(3) se obtendría la quinta letra de la hilera "abc0123" que es '0'. Esta forma de almacenar el valor permite implementar cada rotación con un esfuerzo mínimo, independiente del tamaño de la hilera, de orden O(1): tiempo constante de ejecución. Sin embargo, agregar o eliminar una letra toma tiempo lineal, de orden O(n), donde n==size() es la cantidad de letras de la hilera.

/// Ejercita los métodos del enunciado de la tarea programada.
void test_rotador::test_enunciado() {
{{  // test::enunciado()
    rotador r,v = "0123abc";
    assertTrue( v.at(0)=='0' && v.at(6)=='c' );
                                    // [0123456]
    r = v;            assertTrue( r == "0123abc" && v==r );
    r.rotar( -4 );    assertTrue( r == "abc0123" && v!=r );
    assertTrue( r.at(0)=='a' && r.at(6)=='3' );

                                    // [0123456]
    r = v;            assertTrue( r == "0123abc" && v==r );
    r.rotar(  3 );    assertTrue( r == "abc0123" && v!=r );
    assertTrue( r.at(1)=='b' && r.at(5)=='2' );

                                    // [0123456]
    r = v;            assertTrue( r == "0123abc" && v==r );
    r.dePrimero( 4 ); assertTrue( r == "abc0123" && v!=r );
    assertTrue( r.at(2)=='c' && r.at(1)=='b' );

    r.dePrimero( 0 ); assertTrue( r == "abc0123" && v!=r );
}}
    {   // Resto de las pruebas
        rotador v = "0123abc";
        assertTrue( v.at(0)=='0' && v.at(6)=='c' );
        assertTrue( v.m_idx == 0 && v.m_str == "0123abc" );
        assertTrue( v.size() == v.m_str.size() );

                                        // [0123456]
        rotador r = v;    assertTrue( r == "0123abc" && v==r );
        r.rotar( -4 );    assertTrue( r == "abc0123" && v!=r );
        assertTrue( r.at(0)=='a' && r.at(6)=='3' );

        // Al rotar solo cambia m_idx: m_str mantiene su valor
        assertTrue( r.m_idx == 4 && r.m_str == "0123abc" );
    }
}

Consulta:
Profe: ¿Por qué el método at() tiene la marca '&'?
Respuesta:
Esa marca indica que el método retornar una referencia por lo que en realidad retorna un puntero al valor almacenado:
char& rotador::at( unsigned i );
Consulta:
Profe: ¿Tenemos que implementar el método append()?
Respuesta:
Suena interesante, pero por el momento es optativo, pues en casi todos los casos hay que reconstruir toda la hilera almacenada en la instancia del objeto rotador para agregarle un letra al final.
Consulta:
Profe: Hola profesor, ¿Debo construir solamente las archivo rotador.cpp , rotador.h y test_rotador.cpp para que los casos de prueba BUnit.h funcionen, en base al enunciado de la tarea, o más bien debo construir un programa en que lea del teclado valores para mostrar cómo se procesa la hilera? Me parece poco útil un programa que que interactúe con el usuario.
Respuesta:
Basta con el programa de prueba test_rotador.cpp pues es incómodo meter valores desde la consola para probar un programa.
Consulta:
Profe: ¿Puedo usar un Rep diferente? Me gustaría tener una segunda hilera en la que pueda agregar letras eficientemente.
Respuesta:
No. Si usás un Rep diferente el código de ejemplo de este enunciado no te compilaría.

      Entregue su tarea por correo electrónico, como lo hizo anteriormente.

[mailto:] Entrega de Tareas

Tiempo de entrega: 3 días
Modalidad: En parejas

Soluciones

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