Polyset
Código comentado línea a línea y paso a paso:
Entregas: searchable_array_bag.*, searchable_tree_bag.*, set.*. Flags: c++ -Wall -Wextra -Werror -std=c++98
Qué pide (en palabras normales)
- Te dan una bolsa de números (
bag): meter, imprimir, vaciar. Admite repetidos. - Dos bolsas ya hechas: una guarda en lista (
array_bag), otra en árbol (tree_bag). - Tarea 1: a cada bolsa le añades una pregunta: "¿está este número?" →
has. - Tarea 2: haces un conjunto (
set): una bolsa que no deja meter repetidos. Antes de meter, pregunta conhas.
Subject (enunciado original)
Assigment name: Polyset
Expected File: searchable_array_bag.cpp, searchable_array_bag.hpp,
searchable_tree_bg.cpp, searchable_tree_bag.hpp, set.cpp, set.hpp
You will find in this directory some classes:
- bag: an abstract class representing a bag
- searchable_bag: an abstract class representing a bag with the ability to
search in it.
- array_bag: an implementation of a bag with an array an underlying data
structure.
- tree_bag: an implementation of a bag with a binary search tree as underlying
data structure.
If you don't know what is a set or a bag (shame!) you can read the attached
file shame.en.txt
First Part:
Since a bag without a searching function isn't very useful, implement two
classes searchable_array_bag and searchable_tree_bag, that will inherit from
array_bag and tree_bag and implement the searchable bag abstract class.
Second Part:
Implement the class set that will wrap a searchable_bag and turn it into a set.
You will find in this dir a main that must compile with your code.
All classes should be under orthodox canonical form. Don't forget the const.
[MAIN]
#include "searchable_bag.hpp"
#include "searchable_tree_bag.hpp"
#include "searchable_array_bag.hpp"
#include "set.hpp"
#include <iostream>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc == 1)
return 1;
searchable_bag *t = new searchable_tree_bag;
searchable_bag *a = new searchable_array_bag;
for (int i = 1; i < argc; i++) {
t->insert(atoi(argv[i]));
a->insert(atoi(argv[i]));
}
t->print();
a->print();
for (int i = 1; i < argc; i++)
{
std::cout << t->has(atoi(argv[i])) << std::endl;
std::cout << a->has(atoi(argv[i])) << std::endl;
std::cout << t->has(atoi(argv[i]) - 1) << std::endl;
std::cout << a->has(atoi(argv[i]) - 1) << std::endl;
}
t->clear();
a->clear();
const searchable_array_bag tmp(static_cast<searchable_array_bag &>(*a));
tmp.print();
tmp.has(1);
set sa(*a);
set st(*t);
int intArr[] = {1, 2, 3, 4};
for (int i = 1; i < argc; i++)
{
st.insert(atoi(argv[i]));
sa.insert(atoi(argv[i]));
sa.has(atoi(argv[i]));
sa.print();
sa.get_bag().print();
st.print();
sa.clear();
sa.insert(intArr, sizeof(intArr) / sizeof(int));
std::cout << std::endl;
}
delete a;
delete t;
return (0);
}
Mapa
bag (insert, insert[], print, clear)
/ \ virtual public → diamante
array_bag searchable_bag (+ bool has(int) const = 0)
tree_bag |
\ /
searchable_array_bag / searchable_tree_bag → solo añaden has()
set ──contiene──▶ searchable_bag &bag → NO hereda, delega
3 piezas
1. this = "yo"
this = el objeto que ejecuta la función ("yo"). *this = yo mismo.
2. const al final = "solo miro"
class Contador
{
int n;
public:
void sumar() { n++; } // me cambia → SIN const
int ver() const { return n; } // solo mira → CON const
};
Pregunta única: ¿cambia algo de mi objeto? No → const · Sí → sin const.
Por qué importa: un objeto const solo puede usar funciones const. El main hace const searchable_array_bag tmp(...); tmp.has(1); → has tiene que ser const.
3. return *this = "me devuelvo a mí"
searchable_array_bag& searchable_array_bag::operator=(const searchable_array_bag& other)
{
if (this != &other)
array_bag::operator=(other); // copia el padre
return *this; // me devuelvo a mí
}
En polyset solo sale en operator=. Truco: si ves return *this;, delante va Clase &. Siempre juntos.
Polyset
Con searchable_array_bag. En tree: cambia array → tree.
| Función | ¿Cambia algo? | Firma |
|---|---|---|
| constructor | - | searchable_array_bag(); |
| copia | - | searchable_array_bag(const searchable_array_bag &src); |
| destructor | - | ~searchable_array_bag(); |
= | sí → sin const · return *this | searchable_array_bag &operator=(const searchable_array_bag &src); |
has | no → const | bool has(int value) const; |
| set | ||
| constructor | - | set(searchable_bag &b); |
insert | sí → sin const | void insert(int value); |
clear | sí → sin const | void clear(); |
print | no → const | void print() const; |
has | no → const | bool has(int value) const; |
get_bag | no → const | const searchable_bag &get_bag() const; |
get_bag lleva dos const: delante = "lo que te doy no lo toques" · detrás = "yo no me toco".
Cuerpos
copia : array_bag(other) {}
= if (this != &other) array_bag::operator=(other); return *this;
has (array) bucle i < size → data[i] == value
set(b) : bag(b) {} (referencia → obligatorio aquí)
set::insert if (!bag.has(v)) bag.insert(v);
set() copia = private y sin cuerpo (C++98 no tiene = delete)
resto de set print / clear / has / get_bag → se lo pasa a bag
Optim: declaraciones en el .hpp y cuerpos en el .cpp. En el .cpp lo que sale va delante del dueño: searchable_array_bag &searchable_array_bag::operator=(...)
Cristi: todo escrito dentro del .hpp (cuerpos inline) y los .cpp solo incluyen su .hpp. Menos que escribir, mismo resultado.
has() del árbol
node *cur = tree;
while (cur)
== → true
< → cur->l
> → cur->r
NULL → false
Checklist
#pragma onceen todos los .hpppublic:tras la llave- Segundo padre =
searchable_bag(no tu propia clase) hasconconst(lo exigetmp.has(1)del main);tras la}de la clasesetguarda una referencia: se rellena en: bag(b)y~setno borra nada