Site hosted by Angelfire.com: Build your free website today!

Universidad de Costa Rica

 

Escuela de Ciencias de la
Computación e Informática

 

Tercera Tarea Programada:
Contador de Números

 

CI-1201 Programación II

 

 

Profesor
Adolfo Di Mare

 

 

Estudiantes:
Eileen Rodríguez D. A34418
Katia Montoya M.    A43493

 

 

Grupo 002
II Ciclo 2005

 

 

 

 

 


Tabla de Contenidos

 

Tabla de Contenidos...................................................................................................... . 5

Introducción.........................................................................................................................3

Descripción Problema a Resolver..................................................................................4

    Planteo............................................................................................................................4

Objetivos.......................................................................................................................4

Requerimientos......................................................................................................... 5

Abstracción...........................................................................................................................6

Especificación de la clase.............................................................................6

Operaciones y métodos.........................................................................................6

Eficiencia....................................................................................................................8

Especificación del programa......................................................................... 8

Arquitectura del Programa.............................................................................. 9

Implementación.............................................................................................................. 10

Modelo de la Clase............................................................................................. 10

    Invariante de la Clase…………………………………………………………………………………………11

Arquitectura Interna del Programa........................................................ 12

Compilador Usado.................................................................................................. 13

¿Cómo compilar el programa?....................................................................... 13

Guía del uso del programa.......................................................................................... 13

Datos de prueba del programa................................................................................... 14

Formato de los Datos de Prueba...................................................................14

Entradas Vs Salidas Esperadas del Programa................................. 14

Código Fuente............................................................................................................15

Bibliografía....................................................................................................................... 22

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Introducción

            

            Uno de los principales objetivos dentro de la temática del curso y de ésta tarea programada principalmente, consiste en el hecho de programarla usando especificación en lugar de implementación de una clase.

            La Especificación puede verse como un contrato en el que están definidos todos los servicios que la implementación del módulo es capaz de dar. Muchos autores consideran que una especificación correcta debe estar escrita en un lenguaje formal, matemático. Pero otros sólo requieren de la especificación un alto rigor, con estas tres cualidades:

En pocas palabras, en la especificación no debe sobrar ni faltar nada. Debe estar toda la información esencial para implementar un módulo, y también para usarlo. Además, es conveniente que la especificación sea clara y sencilla de entender, de forma que para usarla el programador no requiera hacer un esfuerzo intelectual más grande de lo necesario.

            Por otro lado, se tiene que la implementación de una clase es un grupo de instrucciones imperativas a ser ejecutadas por el computador, escritas en uno o más lenguajes de programación. Cada implementación es una de las muchas posibles formas de escribir el código de un programa. Cuando se ha usado abstracción como técnica de diseño, cada implementación debe corresponder a alguna especificación pues a partir de la abstracción se llegar a la implementación.

 Mientras con la especificación se define qué hace el programa, en la implementación queda escrito cómo se hace. Por eso, después de que ha sido definida la especificación, en general existen muchas posibles implementaciones diferentes que cumplen con la especificación. Optimizar una implementación significa mejorar el código para escoger una implementación que sea más eficiente.

Tomando como modelo lo anteriormente escrito, se realizará un programa que consista en  recibir una cantidad de números diferentes, y almacenarlos en una  “gran bolsa” o contenedor, en donde se ordene y se indique la cantidad de veces que ha salido cada número, sea éste repetido o no.

            Es posible acceder al programa en sí, desde las direcciones de Internet:

_     http://www.angelfire.com/freak3/a34418

_     http://www.angelfire.com/moon2/a43493

 

 

Descripción Problema a Resolver

Ø      Planteo:

La implementación de un programa ejecutable que permita desarrollar un contenedor de números, es decir, la ejemplificación de una bolsa, la cual contiene hileras de números, con el fin de llegar a demostrar la cantidad de números repetidos dentro de esa hilera. En otras palabras, la implementación del programa consiste en un contenedor que almacene números en conjunto a las veces que han sido agregados a la bolsa, ya que como se comentaba anteriormente, el diseño del programa esta basado en una pequeña bolsa cuya funcionalidad consiste en su capacidad de almacenamiento de números, y el conteo de los mismos.

 

Ø      Objetivo principal:

-          Realizar el programa utilizando la especificación en lugar de la  implementación de una clase.

 

Ø      Objetivos Generales:

-          Entender el proceso de reutilización de código

-          Comprender la elaboración del programa, mediante la vista del código

-          Desarrollar habilidad y facilidad a la hora de la compilación

-          Manejo más rápido mediante un editor de texto de C++, como por ejemplo el Visual Studio 6.0

-          Obtener la solución al problema, la ejecución del contenedor de números.

 

 

Ø      Requerimientos:

-          Compilador C++, ya sea el de Visual Studio 6.0, el Visual Studio.Net  o el Borland C++.

-          Para la ejecución, obviamente se necesita el código fuente (más adelante se presentará).

-          Para mayor entendimiento o claridad, el archivo doxygen, en el cual se muestra más detalladamente la implementación del programa.

-          Alguna guía de compilación y ejecución del programa (más adelante se presentará).

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Abstracción

            Especificación de las Clases

 

Clase Count.cpp:

            En esta clase se sitúa la función principal para la ejecución del programa, es decir, la función main, la cual tiene como fin llamar a funciones de la biblioteca estándar  para llevar a cabo sus tareas. Dentro de la declaración de la clase se desarrolla para qué sirve el programa: para leer números y contar cuántas veces aparece cada uno.

 

Operaciones / Métodos

 

*  int main() : función principal en la que empieza la ejecución del programa

*  Se declara una variable B de tipo Nmbag(constructor) que es la “gran bolsa” donde se acumularán todos los números introducidos por el usuario.

*  Se declara otra variable n de tipo long que representará el número que se esté procesando en el tiempo determinado.

*  while: se introduce la estructura de control, que verifica que los demás números sean mayores que el número en proceso, y que mientras estos sean mayores, que la gran bolsa incremente en uno (1) el valor de la variable n(recordar que la variable n es el número que se está analizando) è B.Inc(n);

*  for: se inicia el ciclo for, y dentro de éste se inicia la estructura if, que se refiere al número en proceso, si éste es diferente de cero, entonces debe aparecer ese número con la frase “está”, luego se le agrega la cantidad de veces que está dicho número en la bolsa, y finalmente debe aparecer la frase “veces en la bolsa”; por ejemplo, si el número es el 8(ocho), y aparece 2(dos) veces en la gran bolsa, el programa debería ejecutar lo siguiente: “8 está 2 veces en la bolsa.”

*  return 0;

 

Clase Nmbag.cpp:

             Se establecen las implementaciones para la clase “Nmbag”. La clase Nmbag almacena números junto a la cantidad de veces que han sido agregados a la bolsa

Funciones / Métodos

o              USING_namespace (ADH)

o        bool  check_ok (const Nmbag &B) = (Verifica la invariante de la clase "Nmbag". )

 

Clase Nmbag.h:

Almacena números junto a la cantidad de veces que han sido agregados a la bolsa.

·         Este es un ejemplo particular de la clase conjunto ( "set" ).

·         La cantidad total de números almacenados en la bolsa no puede exceder "Nmbag::Capacity".

o       Tipos públicos

                 enum  { Capacity = 255 }

o       Métodos públicos

                  1.   Nmbag () è Constructor

            2.  ~Nmbag () è Destructor

3.  Unsigned Qty (long) è Retorna la cantidad de veces que el valor "n" ha sido agregado a la bolsa.

4. Void Inc (long) èIncrementa en uno (1) el valor de "Qty(n)".

5. Unsigned  size () èCantidad de valores no nulos de la bolsa.

6. Unsigned operator[] (long n) è Sinónimo de "Qty(n)".

 

o        Atributos privados

o       Amigas

             bool  check_ok (const Nmbag &r)èVerifica la invariante de la clase "Nmbag".

 

 

 

Eficiencia:

      El programa no es muy eficiente, puesto que no cualquier usuario puede llevar cabo la ejecución, ya que contiene ciertas pautas que a la hora de ejecutar el programa no llegue a suceder nada, a razón de la poca complejidad con la que cuenta el programa y la poca estructuración que se emplea para su realización. Pero a pesar de esto, si el procedimiento para ejecutarlo es el adecuado, entonces el almacenamiento de los números se hará de forma exacta; al igual que el conteo de las veces que cada número esté repetido en la bolsa.

 

Especificación del Programa

Este programa es un contenedor de números que funciona con las siguientes variables:

El funcionamiento es el de almacenar números junto a la cantidad de veces que han sido agregados a la bolsa.

·         Este es un ejemplo particular de la clase conjunto ( "set" ).

·         La cantidad total de números almacenados en la bolsa no puede exceder "Nmbag::Capacity".

 

 

 

 

 

 

 

 

Arquitectura del Programa

 

 


 
Cuadro de texto: ADH_port.h

 


 

       

 

                                                                     


 

Cuadro de texto: Nmbag.obj Cuadro de texto: Count.obj

 


 

Cuadro de texto: Count.exe

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Implementación

 

            Modelo de la Clase

Clase Nmbag.h

·          public:

    enum { Capacity = 255

    };

 

·          public:

    Nmbag() : m_used(0) {}

    ~Nmbag() {} 

         

·          public:

    unsigned Qty(long);

    void     Inc(long);

    unsigned size() { return m_used; }

    unsigned operator[](long n) { return Qty(n); }

    friend bool check_ok( const Nmbag& r )

 

·          private:

    unsigned m_used;          

    unsigned m_count[Capacity];

    long     m_val  [Capacity];

    }; 

 

Clase Nmbag.cpp

§          bool check_ok( const Nmbag& B ) {

   

       

§          unsigned Nmbag::Qty(long n) {

 

§          void Nmbag::Inc(long n) {

   

 

 

Clase Count.cpp

·          int main() {

    Nmbag B;

    long n;

 

       while (cin >> n) {

        B.Inc(n);

    }

 

    for (n=0; n<LONG_MAX/*INT_MAX*/; ++n) {

        if (0 != B[n]) {

            cout << n << " está " << B.Qty(n);

            cout << " veces en la bolsa" << endl;

        }

    }

 

    return 0;

}

 

Invariante de la Clase

            Las invariantes de la clase son:

1.      Un valor de "m_val[]" nunca debe tener asociado 0 (cero) en "m_count[]": esto porque el número se contabiliza al entrar en la bolsa, esto significa que el número ya apareció al menos una(1) vez en “m_count”.

2.      No debe haber valores duplicados en "m_val[]"

Las invariantes del programa son verificadas mediante la siguiente instrucción:

                        bool check_ok ( const Nmbagr[friend]

 

·         Una bolsa contiene 2 vectores: el de los valores almacenados en la bolsa "m_val[]", y el que contiene la cantidad de veces que cada valor aparece en la bolsa "m_count[]".

·         Como estos 2 vectores tienen dimensión "Nmbag::Capacity", sólo es posible almancer un máximo de "Nmbag::Capacity" valores en la bolsa.

·         El valor de "m_used" indica cuántos valores del vector están en uso.

·         Si la bolsa está vacía, su valor "m_used" es cero.

·         En los vectores los campos a partir de "m_val[m_used]" contienen basura porque no están inicializados.

Por ejemplo, la bolsa "B" contiene 3 valores cuya cuenta es mayor a cero:

        B.Qty(315) ==  13        B.Qty(1)  == 0
        B.Qty(212) ==   1        B.Qty(12) == 0
        B.Qty(304) == 500        B.Qty(17) == 0
 
       0     1     2     3     4     5                  Capacity
    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+
    | 315 | 212 | 304 |  1  | @$? | ?!? | ... | @*? | ^-* | ??? | <== m_val[]
    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+
    |  13 |  1  | 500 |  12 | @$? | )!/ | ... | ?!? | @$? | !+* | <== m_count[]
    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+
                        /|\
                         |
    m_used == 3 ---------+

 

 

   

Arquitectura Interna

 

            Este programa está diseñado para el almacenamiento de números. El usuario introduce los datos, estos son internados en el programa, se verifica si la información introducida es compatible con las especificaciones del programa, se realiza el conteo de los números, el programa determina la cantidad de veces que ha aparecido cada número digitado por el usuario, se vincula un espacio en memoria para la información introducida: primero los números según hallan sido introducidos, y luego la frase: “(número) está (cantidad de veces) en la bolsa” , es decir, el resultado es almacenado de tal manera que es devuelto al desplegarse en la pantalla, con la finalidad de demostrar el resultado de la acción solicitada.

 

 

 

 

 

 

 

Compilador Usado

·         Para la ejecución del programa fue utilizado el compilador del Visual Studio 6.0 C++.

 

 

 

Cómo Compilar el Programa?

 

            Primero que todo, se debe buscar si en su computador está instalado un compilador de C++, compatible, en nuestro caso, utilizamos el visual Studio 6.0, para verificar, haga clic en el botón inicio, váyase a archivos de programas, y búsquelo si no, es así puede estar alojado en el archivo, desarrollo, una vez encontrado, haga clic en el icono perteneciente al Visual en este caso, ya abierto el programa, y sin la necesidad de haber creado primeramente un proyecto váyase a files, dele clic en el botón open, y seleccione los archivos conjunto para poder compilarlos, claro, está es necesario tener los archivos guardados ya sea en su computador, o bien en un disquete o CD, una vez ubicados los archivos haga clic en abrir, e inmediatamente le aparecerán los archivos dentro del visual, ya sea que los vaya abriendo uno por uno, o todos a la vez. Ya hecho esto, digite control + f7 o bien al lado izquierdo dentro de la barra superior hay un icono con una flechita para abajo, esto le permitirá compilar el programa, seguidamente, digite f7, para darle build y tener listo el programa, seguidamente seleccione control + f5 y su programa se ejecutará, si no se ejecuta inmediatamente podrá ser porque necesita el proyecto, sin embargo el computador se lo hará saber, mediante una ventanita de advertencia, haga clic en sí, y eso permitirá que se cree, permitiendo la ejecución del programa.

 

 

Guía de Uso del Programa

 

            En el caso de que quiera bajar el programa de internet, que lo puede encontrar en www.angelfire.com/freak3/a34418 o www.angelfire.com/moon2/a43493 , en el link de tareas, haga clic si desea guardarlo o si desea abrirlo, seguidamente guárdelo en un dispositivo, abra el visual Studio, compílelo, y seguidamente ejecútelo.

Datos de Prueba del Programa

            Formato de los Datos de Prueba        

           

Los datos de prueba consisten en la cantidad de números almacenados en la bolsa, determinado por la variable m_used, los cuales no deben exceder la capacidad de almacenamiento del programa. Éstos son evaluados mediante el vector m_count, que tiene como asignación el conteo de qué tantas “n” veces se encuentra m_val en la bolsa. Asimismo, se necesitará evaluar el “n” que aparece más de una vez dentro la bolsa. Aclarado esto, se ejecutará el programa dándole la opción al usuario de agregar la cantidad de números que desee dentro de la bolsa; de tal manera que escribiendo un punto al final de la hilera, llegue a mostrarse el desglose de qué tantas veces se encuentran los números alojados en la bolsa.

 

Entradas vs Salidas Esperadas

1

2

3

 

3

3

3

3

3

3

3

3

3

3

3

4

5

6

7

8

3

 

123

123

123

123 está 3 veces en la bolsa

 

                Código Fuente

// Nmbag.h   (C) 2005  adolfo@di-mare.com

 

/** \file  Nmbag.h

    \brief Números junto la cantidad de veces que aparecen en la bolsa

 

    \author Adolfo Di Mare <adolfo@di-mare.com>

    \date   2005

*/

 

#ifndef  Nmbag_h

#define  Nmbag_h ///< Evita la inclusión múltiple

 

#define  INCLUDE_iostream

#include "ADH_port.h"

#include <cstring>

 

OPEN_namespace(ADH)

 

/** Almacena números junto a la cantidad de veces que han sido agregados a la bolsa.

 

    - Este es un ejemplo particular de la clase conjunto ( \c "set" ).

    - La cantidad total de números almacenados en la bolsa no puede exceder

      \c "Nmbag::Capacity".

*/

class Nmbag {

public:

    enum { Capacity = 255 ///< Cantidad máxima de números que puede almacenar la bolsa

    }; // BC++ v3.1 no facilita usar constantes estáticas

public:

    Nmbag() : m_used(0) {} ///< Contructor

    ~Nmbag() {}            ///< Destructor

public:

    unsigned Qty(long);

    void     Inc(long);

    unsigned size() { return m_used; } ///< Cantidad de valores no nulos de la bolsa

 

    unsigned operator[](long n) { return Qty(n); } ///< Sinónimo de \c "Qty(n)"

 

    friend bool check_ok( const Nmbag& r ); // Ok()

 

private:

    unsigned m_used;            ///< Cantidad de valores almacenados en la bolsa

    unsigned m_count[Capacity]; ///< Cantidad de veces que \c "m_val[i]" aparece

    long     m_val  [Capacity]; ///< Valor \c "n" que aparece más de 1 vez en la bolsa

}; //

 

CLOSE_namespace(ADH)

 

#endif // Nmbag_h

 

// EOF: Nmbag.h

 

 

 

// Nmbag.cpp (C) 2005  adolfo@di-mare.com

 

/** \file Nmbag.cpp

    \brief Implementaciones para la clase \c "Nmbag"

 

    \author Adolfo Di Mare <adolfo@di-mare.com>

    \date   2005

 

    - Why English names??? ==> http://www.di-mare.com/adolfo/binder/c01.htm#sc04

*/

 

#include "Nmbag.h"

 

OPEN_namespace(ADH)

USING_namespace(ADH);

 

#include "assert.h"

 

/** Verifica la invariante de la clase \c "Nmbag"

 

    - Una bolsa contiene 2 vectores: el de los valores almacenados en la

      bolsa \c "m_val[]", y el que contiene la cantidad de veces que

      cada valor aparece en la bolsa \c "m_count[]".

 

    - Como estos 2 vectores tienen dimensión \c "Nmbag::Capacity", sólo

      es posible almancer un máximo de \c "Nmbag::Capacity" valores en

      la bolsa.

 

    - El valor de \c "m_used" indica cuántos valores del vector están

      en uso.

 

    - Si la bolsa está vacía, su valor \c "m_used" es cero.

 

    - En los vectores los campos a partir de \c "m_val[m_used]" contienen

      basura porque no están inicializados.

 

    Por ejemplo, la bolsa \c "B" contiene 3 valores cuya cuenta es mayor a cero:

    \code

        B.Qty(315) ==  13        B.Qty(1)  == 0

        B.Qty(212) ==   1        B.Qty(12) == 0

        B.Qty(304) == 500        B.Qty(17) == 0

 

       0     1     2     3     4     5                  Capacity

    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+

    | 315 | 212 | 304 |  1  | @$? | ?!? | ... | @*? | ^-* | ??? | <== m_val[]

    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+

    |  13 |  1  | 500 |  12 | @$? | )!/ | ... | ?!? | @$? | !+* | <== m_count[]

    +-----+-----+-----+-----+-----+-----+ ... +-----+-----+-----+

                        /|\

                         |

    m_used == 3 ---------+

    \endcode

 

    \remark

    Libera al programador de implementar el método \c Ok()

    - http://www.di-mare.com/adolfo/binder/c04.htm#sc11

*/

bool check_ok( const Nmbag& B ) {

    assert( true && "NO IMPLEMENTADO ==> check_ok( const & )" );

    unsigned i;

    for (i = 0; i<B.m_used; ++i) {

        if (B.m_count[i] <= 0) {

            return false; /// - Invariante: Un valor de \c "m_val[]" nunca debe tener asocioado \c 0 (cero) en \c "m_count[]"

        }

    }

 

    {   long V [ Nmbag::Capacity ];

        for ( i = 0; i < B.m_used; ++i ) { // copia

            V[i] = B.m_val[i];

        }

 

        unsigned j;

        for ( i=0; i < B.m_used-1; ++i ) {        // Ordena V[]

            for ( j = 0; j < B.m_used-1; ++j ) {

                if ( V[i] > V[i+1] ) {            // Swap(V[i], V[i+1]

                    long tmp = V[i];

                    V[i]   = V[i+1];

                    V[i+1] = tmp;

                }

            }

        }

        for ( i = 0; i < B.m_used-1; ++i ) { // copia

            if (V[i] == V[i+1]) {

                return false; /// - Invariante: No debe haber valores duplicados en \c "m_val[]"

            }

        }

 

    }

 

    return true;

} // check_ok()

 

/** Retorna la cantidad de veces que el valor \c "n" ha sido

    agregado a la bolsa.

 

    - Retorna cero \c (0) si \c "n" nunca ha sido agregado.

*/

unsigned Nmbag::Qty(long n) {

      unsigned i;

              for (i=0; i<m_used;i++){

                        if (m_val[i]==n){         

                                   return m_count[i];

                        }

            }

            return 0;

} // Nmbag::Qty()

 

/** Incrementa en uno \c (1) el valor de \c "Qty(n)"

 

    - Si <code> size() == Nmbag::Capacity </code> sólo puede agregar

      números duplicados.

 

    \pre

    <code> size() < Nmbag::Capacity </code>

*/

void Nmbag::Inc(long n) {

    unsigned i;

            if (m_used < Capacity){

                        m_val[m_used]=n;

                        m_count[m_used]=1;

                        m_used++;

            }

            for (i=0; i< m_used; i++){

                        if (m_val[i]==n){

                                   m_count[i]++;

                        } return ;

                       

            }

           

} // Nmbag::Inc()

 

CLOSE_namespace(ADH)

 

// EOF: Nmbag.cpp

 

 

 

// Count.cpp  (c) 2005 adolfo@di-mare.com

 

/** \file Count.cpp

    \brief Lee números y cuenta la cantidad de veces que cada número aparece.

 

    \author Adolfo Di Mare <adolfo@di-mare.com>

    \date   2005

*/

 

#include "Nmbag.h"

 

USING_namespace(ADH);

 

#include <iostream>

#include <climits>

 

/// Función principal en la que empieza la ejecución del programa

int main() {

    Nmbag B; // Bolsota de números

    long n; // número en proceso

 

    // lee todos los valores

    while (cin >> n) {

        B.Inc(n);

    }

 

    for (n=0; n<25; ++n) {

        if (0 != B[n]) {

            cout << n << " está " << B.Qty(n);

            cout << " veces en la bolsa" << endl;

                                           }

    }

 

    return 0;

} // main()

 

// EOF: Count.cpp

 

 

 

 

 

 

 

 

Bibliografía

*  Deitel, Harvey M. y Deitel, Paul J. Cómo programar en C++. Cuarta Edición. Editorial Prentice Hall. México 2003.

*      Escuela de Ciencias de la Computación e Informática, Universidad de Costa Rica, 1994. 
      http://www.di-mare.com/adolfo/p/list.htm
*  Escuela de Ciencias de la Computación e Informática, Universidad de Costa Rica,1994.
                  http://www.di-mare.com/adolfo/p/list.htm
*  Di Mare, Adolfo. La implementación de Rational.pas. Reporte Técnico ECCI-94-03. Proyecto 326-89-019