]> git.llucax.com Git - z.facultad/75.29/susanita.git/blob - src/persona.cpp
607e0e8a0d36f0fff0464c9cdcb3490d61984e4c
[z.facultad/75.29/susanita.git] / src / persona.cpp
1 #include "persona.h"
2 #include <algorithm>
3 #include <cassert>
4
5 /// Constructor
6 Persona::
7 Persona(const std::string& nombre, sexo_type sexo, size_type cap):
8         nombre(nombre), prefs_hash(cap), estado(SOLTERO), sexo(sexo),
9         pareja(0), rechazos(cap)
10 {
11 }
12
13 /// Para representación
14 std::ostream&
15 operator<< (std::ostream& os, const Persona::estado_type e)
16 {
17         switch (e)
18         {
19                 case Persona::SOLTERO:
20                         return os << "soltero";
21                 case Persona::DECLARADO:
22                         return os << "declarado";
23                 case Persona::COMPROMETIDO:
24                         return os << "comprometido";
25                 default:
26                         assert("Estado de la persona desconocido");
27                         return os << "desconocido";
28         }
29 }
30
31 /// Para representación
32 std::ostream&
33 operator<< (std::ostream& os, const Persona::sexo_type s)
34 {
35         switch (s)
36         {
37                 case Persona::M:
38                         return os << "M";
39                 case Persona::F:
40                         return os << "F";
41                 default:
42                         assert("Sexo de la persona desconocido");
43                         return os << "desconocido";
44         }
45 }
46
47 /// Para representación
48 std::ostream&
49 operator<< (std::ostream& os, const Persona& p)
50 {
51         std::string pareja = "-";
52         if (p.pareja)
53         {
54                 pareja = p.pareja->nombre;
55         }
56         os << "<" << p.nombre << " (" << p.sexo << "): " << p.estado << " - "
57                 << pareja << ">";
58         return os;
59 }
60
61 /// Función de comparación entre dos personas según nuestras preferencias
62 int
63 Persona::
64 cmp(const Persona& p1, const Persona& p2) const // O(1)
65 {
66         int i1 = prefs_hash.get(p1.nombre); // O(1)
67         int i2 = prefs_hash.get(p2.nombre); // O(1)
68
69         if (i1 < i2)
70                 return 1;
71         if (i1 == i2)
72                 return 0;
73         return -1;
74 }
75
76 // Para que no se exporte el símbolo, es de uso interno de este módulo
77 namespace
78 {
79         /// Functor de ordenamiento auxiliar
80         struct PersonaCmp
81         {
82                 Persona& p;
83                 PersonaCmp(Persona& p): p(p) {}
84                 /// devuelve true si p1 < p2
85                 bool operator ()(const Persona* const p1, const Persona* const p2)
86                 {
87                         return p.cmp(*p1, *p2) < 0; // O(N)
88                 }
89         };
90 }
91
92 /// Ordenamos las ofertas segun nuestras preferencias
93 void
94 Persona::
95 ordenar_ofertas() // O(N^2.log(N^2))
96 {
97         // este sort es in-place y O(N.log(N))
98         // Más info en: http://www.sgi.com/tech/stl/sort.html
99         // Pero el PersonaCmp() es O(N)
100         std::sort(ofertas.begin(), ofertas.end(), PersonaCmp(*this));
101 }
102
103 /// Nos declaramos a la persona p
104 void
105 Persona::
106 declarar_a(Persona& p) // O(1)
107 {
108         estado = DECLARADO;
109         pareja = &p;
110         p.ofertas.push_back(this); // O(1)
111 }
112
113 /// Nos comprometemos con la persona p, quien se nos habia declarado previamente
114 void
115 Persona::
116 comprometer_con(Persona& p) // O(N) ( es O(len(ofertas)) )
117 {
118         assert(p.estado == DECLARADO);
119         assert(p.pareja == this);
120
121         // rompemos el compromiso, si hay
122         if (estado == COMPROMETIDO)
123         {
124                 assert(pareja != 0);
125                 pareja->estado = SOLTERO;
126                 pareja->pareja = 0;
127                 pareja->rechazos[this->nombre] = this; // O(1)
128         }
129
130         // nos comprometemos
131         estado = COMPROMETIDO;
132         pareja = &p;
133         p.estado = COMPROMETIDO;
134         p.pareja = this;
135
136         // si tenemos ofertas, las rechazamos
137         for (ofertas_type::iterator pretendiente = ofertas.begin(); // O(N)
138                         pretendiente != ofertas.end(); ++pretendiente)
139         {
140                 (*pretendiente)->rechazos[this->nombre] = this; // O(1)
141         }
142         ofertas.clear(); // O(N)
143 }
144
145 // Nos comprometemos con la otra persona y a ella la comprometemos con nosotros
146 void
147 Persona::
148 comprometer_con_bt(Persona& p)
149 {
150         // nos comprometemos
151         estado = COMPROMETIDO;
152         pareja = &p;
153         p.estado = COMPROMETIDO;
154         p.pareja = this;
155 }
156
157 // Rompemos el compromiso existente
158 void
159 Persona::
160 romper_compromiso(Persona& p)
161 {
162         assert(pareja == &p);
163         assert(p.pareja == this);
164         
165         // rompemos el compromiso
166         estado = SOLTERO;
167         pareja = 0;
168         p.estado = SOLTERO;
169         p.pareja = 0;
170 }
171
172