]> git.llucax.com Git - z.facultad/75.29/susanita.git/blob - src/persona.cpp
c93b069da73eca1ea5d501f0c0ebbfcd9a9473d7
[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), estado(SOLTERO), sexo(sexo), pareja(0), rechazos(cap)
9 {
10 }
11
12 /// Para representación
13 std::ostream&
14 operator<< (std::ostream& os, const Persona::estado_type e)
15 {
16         switch (e)
17         {
18                 case Persona::SOLTERO:
19                         return os << "soltero";
20                 case Persona::DECLARADO:
21                         return os << "declarado";
22                 case Persona::COMPROMETIDO:
23                         return os << "comprometido";
24                 default:
25                         assert("Estado de la persona desconocido");
26                         return os << "desconocido";
27         }
28 }
29
30 /// Para representación
31 std::ostream&
32 operator<< (std::ostream& os, const Persona::sexo_type s)
33 {
34         switch (s)
35         {
36                 case Persona::M:
37                         return os << "M";
38                 case Persona::F:
39                         return os << "F";
40                 default:
41                         assert("Sexo de la persona desconocido");
42                         return os << "desconocido";
43         }
44 }
45
46 /// Para representación
47 std::ostream&
48 operator<< (std::ostream& os, const Persona& p)
49 {
50         std::string pareja = "-";
51         if (p.pareja)
52         {
53                 pareja = p.pareja->nombre;
54         }
55         os << "<" << p.nombre << " (" << p.sexo << "): " << p.estado << " - "
56                 << pareja << ">";
57         return os;
58 }
59
60 /// Función de comparación entre dos personas según nuestras preferencias
61 int
62 Persona::
63 cmp(const Persona& p1, const Persona& p2) const // O(N)
64 {
65         prefs_type::const_iterator pos_p1
66                 = std::find(prefs.begin(), prefs.end(), &p1); // O(N)
67         prefs_type::const_iterator pos_p2
68                 = std::find(prefs.begin(), prefs.end(), &p2); // O(N)
69         if (pos_p1 < pos_p2)
70                 return 1;
71         if (pos_p1 == pos_p2)
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