Data Structures

Lab #1: DinoSets

Objective

During this activity, students will be able to:


Description

This activity must be developed in the pre-assigned teams of two.

Your good friend, paleontologist Alan Grant, has asked you to implement a C++ class that allows working with sets of dinosaurs (DinoSet) in order to develop a project for mangaging fossils of saurian species found in different excavation locations.

A set is a collection of well-defined elements without repetitions. A DinoSet can be implemented using a boolean array with a size equal to the number of dinosaur species we want to represent. Each element in the array represents the presence or absence of a dinosaur species within the DinoSet.

The specific species of dinosaurs that are required in your DinoSet class can be represented as a C++ enumeration:

enum class DinoId {
    velociraptor,        // 0
    stegosaurus,         // 1
    tyrannosaurus,       // 2
    procompsognathus,    // 3
    triceratops,         // 4
    pachycephalosaurus,  // 5
    parasaurolophus,     // 6
    pteranodon           // 7
};

The integer values in the code comments above correspond to an index in the boolean array. So, for example, if array location 0 is true, it means that the array contains a velociraptor. In case the array location 0 equals false, then the array does not contain a velociraptor. The DinoId enumeration allows dinosaurs to be referred to by name rather than number, i.e. instead of referring to dinosaur 1, one must refer to dinosaur DinoId::stegosaurus, which makes the program more legible.

The member functions of the DinoSet class are described below:

Función Descripción
void add(DinoId id) Adds to this object the element specified by the DinoId taken as input.
void remove(DinoId id) Removes from this object the element specified by the DinoId taken as input.
bool contains(
    DinoId id
) const
Returns true if this object contains the DinoId taken as input, or false otherwise.
int size() const Returns the number of elements contained in this object.
bool is_empty() const Returns true if this object is an empty set (has zero elements), or false otherwise.
DinoSet operator+(
    const DinoSet& other
) const
Union: returns a new DinoSet consisting of all the elements contained in this object and/or in the DinoSet taken as input.
DinoSet operator*(
    const DinoSet& other
) const
Intersection: returns a new DinoSet consisting of all the elements contained in this object and also in the DinoSet taken as input.
DinoSet operator-(
    const DinoSet& other
) const
Difference: returns a new DinoSet consisting of all the elements contained in this object but that are not contained in the DinoSet taken input.
DinoSet operator!() const Complement: returns a new DinoSet consisting of all those elements that are not contained in this object.
bool operator==(
    const DinoSet& other
) const
Returns true if the DinoSet taken as input contains exactly the same elements as this object. Otherwise it returns false.
std::string to_string()
    const
Returns the representation of this object as string of characters. The precise format can be seen in the examples below.

Place all your code in a file called dinoset.h. Test your class implementation with the following unit tests (it contains a total of 93 assertions):

#include "catch.h"
#include "dinoset.h"

TEST_CASE("test the DinoSet class")
{
    DinoSet a;

    DinoSet b;
    b.add(DinoId::velociraptor);
    b.add(DinoId::tyrannosaurus);

    DinoSet c;
    c.add(DinoId::tyrannosaurus);
    c.add(DinoId::procompsognathus);
    c.add(DinoId::pteranodon);

    SECTION("test to_string") {
        REQUIRE(a.to_string() == "{}");
        REQUIRE(b.to_string() == "{velociraptor, tyrannosaurus}");
        REQUIRE(c.to_string()
            == "{tyrannosaurus, procompsognathus, pteranodon}");
    }

    SECTION("test contains") {
        REQUIRE_FALSE(a.contains(DinoId::velociraptor));
        REQUIRE_FALSE(a.contains(DinoId::stegosaurus));
        REQUIRE_FALSE(a.contains(DinoId::tyrannosaurus));
        REQUIRE_FALSE(a.contains(DinoId::procompsognathus));
        REQUIRE_FALSE(a.contains(DinoId::triceratops));
        REQUIRE_FALSE(a.contains(DinoId::pachycephalosaurus));
        REQUIRE_FALSE(a.contains(DinoId::parasaurolophus));
        REQUIRE_FALSE(a.contains(DinoId::pteranodon));

        REQUIRE(b.contains(DinoId::velociraptor));
        REQUIRE_FALSE(b.contains(DinoId::stegosaurus));
        REQUIRE(b.contains(DinoId::tyrannosaurus));
        REQUIRE_FALSE(b.contains(DinoId::procompsognathus));
        REQUIRE_FALSE(b.contains(DinoId::triceratops));
        REQUIRE_FALSE(b.contains(DinoId::pachycephalosaurus));
        REQUIRE_FALSE(b.contains(DinoId::parasaurolophus));
        REQUIRE_FALSE(b.contains(DinoId::pteranodon));

        REQUIRE_FALSE(c.contains(DinoId::velociraptor));
        REQUIRE_FALSE(c.contains(DinoId::stegosaurus));
        REQUIRE(c.contains(DinoId::tyrannosaurus));
        REQUIRE(c.contains(DinoId::procompsognathus));
        REQUIRE_FALSE(c.contains(DinoId::triceratops));
        REQUIRE_FALSE(c.contains(DinoId::pachycephalosaurus));
        REQUIRE_FALSE(c.contains(DinoId::parasaurolophus));
        REQUIRE(c.contains(DinoId::pteranodon));
    }

    SECTION("test size") {
        REQUIRE(a.size() == 0);
        REQUIRE(b.size() == 2);
        REQUIRE(c.size() == 3);
    }

    SECTION("test is_empty") {
        REQUIRE(a.is_empty());
        REQUIRE_FALSE(b.is_empty());
        REQUIRE_FALSE(c.is_empty());
    }

    SECTION("test remove") {
        REQUIRE(c.size() == 3);
        REQUIRE(c.contains(DinoId::procompsognathus));
        c.remove(DinoId::procompsognathus);
        REQUIRE(c.size() == 2);
        REQUIRE_FALSE(c.contains(DinoId::procompsognathus));
        REQUIRE(c.to_string() == "{tyrannosaurus, pteranodon}");
        REQUIRE(c.contains(DinoId::tyrannosaurus));
        c.remove(DinoId::tyrannosaurus);
        REQUIRE(c.size() == 1);
        REQUIRE_FALSE(c.contains(DinoId::tyrannosaurus));
        REQUIRE(c.to_string() == "{pteranodon}");
        REQUIRE(c.contains(DinoId::pteranodon));
        c.remove(DinoId::pteranodon);
        REQUIRE(c.is_empty());
        REQUIRE_FALSE(c.contains(DinoId::pteranodon));
        REQUIRE(c.to_string() == "{}");

        REQUIRE(b.size() == 2);
        REQUIRE(b.contains(DinoId::tyrannosaurus));
        b.remove(DinoId::tyrannosaurus);
        REQUIRE(b.size() == 1);
        REQUIRE_FALSE(b.contains(DinoId::tyrannosaurus));
        REQUIRE(b.to_string() == "{velociraptor}");
        REQUIRE(b.contains(DinoId::velociraptor));
        b.remove(DinoId::velociraptor);
        REQUIRE(b.is_empty());
        REQUIRE_FALSE(b.contains(DinoId::velociraptor));
        REQUIRE(b.to_string() == "{}");

        REQUIRE(a.is_empty());
        REQUIRE_FALSE(a.contains(DinoId::tyrannosaurus));
        a.remove(DinoId::tyrannosaurus);
        REQUIRE(a.is_empty());
        REQUIRE_FALSE(a.contains(DinoId::tyrannosaurus));
        REQUIRE(a.to_string() == "{}");
        REQUIRE_FALSE(a.contains(DinoId::pteranodon));
        a.remove(DinoId::pteranodon);
        REQUIRE(a.is_empty());
        REQUIRE_FALSE(a.contains(DinoId::pteranodon));
        REQUIRE(a.to_string() == "{}");
    }

    SECTION("test +") {
        REQUIRE((a + b).to_string()
            == "{velociraptor, tyrannosaurus}");
        REQUIRE((a + c).to_string()
            == "{tyrannosaurus, procompsognathus, pteranodon}");
        REQUIRE((b + c).to_string()
            == "{velociraptor, tyrannosaurus, procompsognathus, "
               "pteranodon}");
        REQUIRE((c + b).to_string()
            == "{velociraptor, tyrannosaurus, procompsognathus, "
               "pteranodon}");
    }

    SECTION("test *") {
        REQUIRE((a * b).to_string() == "{}");
        REQUIRE((a * c).to_string() == "{}");
        REQUIRE((b * c).to_string() == "{tyrannosaurus}");
        REQUIRE((c * b).to_string() == "{tyrannosaurus}");
    }

    SECTION("test -") {
        REQUIRE((a - b).to_string() == "{}");
        REQUIRE((b - a).to_string()
            == "{velociraptor, tyrannosaurus}");
        REQUIRE((a - c).to_string() == "{}");
        REQUIRE((c - a).to_string()
            == "{tyrannosaurus, procompsognathus, pteranodon}");
        REQUIRE((b - c).to_string() == "{velociraptor}");
        REQUIRE((c - b).to_string()
            == "{procompsognathus, pteranodon}");
    }

    SECTION("test !")
    {
        REQUIRE((!a).to_string()
            == "{velociraptor, stegosaurus, tyrannosaurus, "
               "procompsognathus, triceratops, pachycephalosaurus, "
               "parasaurolophus, pteranodon}");
        REQUIRE((!b).to_string()
            == "{stegosaurus, procompsognathus, triceratops, "
               "pachycephalosaurus, parasaurolophus, pteranodon}");
        REQUIRE((!c).to_string()
            == "{velociraptor, stegosaurus, triceratops, "
               "pachycephalosaurus, parasaurolophus}");
    }

    SECTION("test ==") {
        DinoSet x;

        DinoSet y;
        y.add(DinoId::tyrannosaurus);
        y.add(DinoId::velociraptor);

        DinoSet z;
        z.add(DinoId::procompsognathus);
        z.add(DinoId::pteranodon);
        z.add(DinoId::tyrannosaurus);

        REQUIRE(a == a);
        REQUIRE(a == x);
        REQUIRE_FALSE(a == y);
        REQUIRE_FALSE(a == z);

        REQUIRE(b == b);
        REQUIRE_FALSE(b == x);
        REQUIRE(b == y);
        REQUIRE_FALSE(b == z);

        REQUIRE(c == c);
        REQUIRE_FALSE(c == x);
        REQUIRE_FALSE(c == y);
        REQUIRE(c == z);
    }
}

Deliverables

Place in a comment at the top of the dinoset.h source file the authors’ personal information (student ID and name), for example:

/*----------------------------------------------------------
 * Lab #1: DinoSets
 * Implementation of the DinoSet class.
 *
 * Date: 19-Aug-2022
 * Authors:
 *           A01770771 Kamala Khan
 *           A01777771 Carol Danvers
 *----------------------------------------------------------*/

Upload Instructions

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

Request PIN

Only one team member needs to upload the file.

Due date is Friday, August 26.