Data Structures

Práctica #3: DinoSets

Objetivo

Durante esta actividad, los alumnos serán capaces de:


Descripción

Tu buen amigo paleontólogo, Alan Grant, te ha pedido que implementes una clase en C++ que permita manejar conjuntos de dinosaurios (DinoSets) con el fin de desarrollar un proyecto para el control de fósiles de especies de saurios encontrados en diferentes localidades en donde están realizado escavaciones.

Un conjunto es una colección de elementos bien definidos sin repeticiones. Un DinoSet se puede implementar utilizando un arreglo de booleanos de un tamaño igual a la cantidad de especies de dinosaurios a representar. Cada localidad del arreglo representa la presencia o ausencia de una especie de dinosaurio dentro del DinoSet.

Las especies particulares de dinosaurios que se requieren en tu clase DinoSet se puede reperesentar como una enumeración de C++:

enum class DinoId {
    velocirraptor,      // 0
    estegosaurio,       // 1
    tiranosaurio,       // 2
    procompsagnatus,    // 3
    triceratops,        // 4
    paquicefalosaurio,  // 5
    parasaurolofus,     // 6
    pteranodon          // 7
};

El número entero en los comentarios del código anterior corresponde a un índice dentro del arreglo de booleanos. Entonces, por ejemplo, si la localidad 0 del arreglo vale true, quiere decir que el conjunto contiene al velocirraptor. En caso de que la localidad 0 del arreglo sea igual a false, entonces el conjunto no contiene al velocirraptor. La enumeración DinoId permite referirse a los dinosaurios por nombre en lugar de número, es decir, en lugar de referirse al dinosaurio 1, se debe uno referir al dinosaurio DinoId::estegosaurio, lo cual facilita la legibilidad del programa.

Las funciones miembro de la clase DinoSet se describen a continuación:

Función Descripción
bool contains(DinoId) const Regresa true si el DinoId que toma como entrada representa un elemento contenido en el objeto receptor, o false en caso contrario.
void add(DinoId) Agrega al objeto receptor el elemento indicado por el DinoId de entrada.
void remove(DinoId) Elimina del objeto receptor el elemento indicado por el DinoId de entrada.
bool is_empty() const Regresa true si el objeto receptor es un conjunto vacío, o false de otra forma.
int size() const Regresa el número de elementos contenidos en el objeto receptor.
DinoSet operator+(
    const DinoSet&
) const
Unión: devuelve un nuevo DinoSet conformado por todos los elementos contenidos en el objeto receptor y/o en el DinoSet que se recibe como entrada.
DinoSet operator*(
    const DinoSet&
) const
Intersección: devuelve un nuevo DinoSet conformado por todos los elementos contenidos en el objeto receptor y en el DinoSet que se recibe como entrada.
DinoSet operator-(
    const DinoSet&
) const
Diferencia: devuelve un nuevo DinoSet conformado por todos los elementos contenidos en el objeto receptor pero que no están contenidos en el DinoSet que se recibe como entrada.
DinoSet operator!() const Complemento: devuelve un nuevo DinoSet conformado por todos aquellos elementos que no pertenecen al objeto receptor.
bool operator==(
    const DinoSet&
) const
Regresa true si la entrada contiene exactamente los mismos elementos que el objeto receptor. En otro caso regresa false.
string to_string() const Devuelve la representación del objeto receptor como una cadena de caracteres. Ver ejemplos más adelante para conocer el formato preciso.

Así mismo el operador << debe sobrecargarse correctamente para poder imprimir un DinoSet usando el objeto cout.

Coloca todo tu código en un archivo llamado dinoset.cpp. Prueba la implementación de la clase con la siguiente función main:

int main()
{
    cout << boolalpha;

    DinoSet a;
    a.add(DinoId::velocirraptor);
    a.add(DinoId::tiranosaurio);
    cout << "a = " << a << endl;

    DinoSet b;
    b.add(DinoId::tiranosaurio);
    b.add(DinoId::procompsagnatus);
    cout << "b = " << b << endl;

    cout << "a contains velociraptor: "
        << a.contains(DinoId::velocirraptor) << endl;
    cout << "a contains procompsagnatus: "
        << a.contains(DinoId::procompsagnatus) << endl;

    DinoSet c = a + b;
    cout << c << endl;
    cout << "size of c: " << c.size() << endl;

    DinoSet d = a * b;
    cout << "d = " << d << endl;

    cout << "d is_empty: " << d.is_empty() << endl;
    d.remove(DinoId::tiranosaurio);
    cout << "d = " << d << endl;
    cout << "d is_empty: " << d.is_empty() << endl;
    cout << "size of d: " << d.size() << endl;

    DinoSet e = a - b;
    cout << "e = " << e << endl;

    DinoSet f = !a;
    cout << "f = "<< f << endl;

    cout << "a == b: " << (a == b) << endl;

    DinoSet g;
    g.add(DinoId::velocirraptor);
    cout << "g = " << g << endl;
    cout << "e == g: " << (e == g) << endl;

    return 0;
}

La salida del programa anterior sería:

a = {velocirraptor, tiranosaurio}
b = {tiranosaurio, procompsagnatus}
a contains velociraptor: true
a contains procompsagnatus: false
{velocirraptor, tiranosaurio, procompsagnatus}
size of c: 3
d = {tiranosaurio}
d is_empty: false
d = {}
d is_empty: true
size of d: 0
e = {velocirraptor}
f = {estegosaurio, procompsagnatus, triceratops, paquicefalosaurio,
parasaurolofus, pteranodon}
a == b: false
g = {velocirraptor}
e == g: true

Durante la clase del 21 de agosto y en los equipos definidos por el profesor, comienza a escribir la clase DinoSet tal como está aquí especificada. Lo que no termine el equipo deberás concluirlo por tu cuenta y entregarlo de manera individual. Durante la clase del 26 de agosto se resolverán las dudas que todavía pudieran existir sobre este ejercicio.

No olvides colocar tu matrícula y nombre en un comentario en la parte superior de tu archivo fuente dinoset.cpp.

Upload Instructions

To deliver the dinoset.cpp file, please provide the following information:

Request PIN

La fecha límite es el miércoles 26 de agosto.