]> git.llucax.com Git - z.facultad/75.29/susanita.git/blob - src/parser.cpp
tagged entrega1
[z.facultad/75.29/susanita.git] / src / parser.cpp
1 #include "parser.h"
2 #include <string>
3 #include <cassert>
4 #include <sstream>
5 #include <fstream>
6 #include <iostream>
7 #include <algorithm>
8
9 Parser::
10 Parser(Susanita& s):
11         susanita(s)
12 {
13 }
14
15 // Para no exportar los símbolos (uso interno de este módulo)
16 namespace
17 {
18         /// Saca espacios de una palabra
19         std::string strip(std::string s) {
20                 std::string ws = " \t\n";
21                 int first = s.find_first_not_of(ws);
22                 int last = s.find_last_not_of(ws);
23
24                 if (first == -1) {
25                         int pos_first = s.find_first_of(ws);
26                         if (pos_first == -1) {
27                                 return s;
28                         } else {
29                                 return std::string("");
30                         }
31                 }
32                 return s.substr(first,last-first+1).c_str();
33         }
34
35         /// Devuelve palabra hasta el caracter indicado
36         std::string get_hasta(std::istream& is, char hasta)
37         {
38                 std::string s;
39                 std::getline(is, s, hasta);
40                 return strip(s);
41         }
42 }
43
44 bool
45 Parser::
46 input(const std::string& filename)
47 {
48         std::ifstream f(filename.c_str());
49         if (!f)
50                 return false;
51         Persona::sexo_type sexo = Persona::M;
52         Persona::sexo_type opuesto = Persona::F;
53
54         Susanita::size_type cap = get_n(filename);
55
56         std::string l;
57         while (std::getline(f, l))
58         {
59                 l = strip(l);
60                 // la linea vacia alterna de sexo
61                 if (l.empty())
62                 {
63                         sexo = Persona::F;
64                         opuesto = Persona::M;
65                         continue;
66                 }
67
68                 // obtenemos el nombre y la lista
69                 std::istringstream ss(l);
70                 std::string nombre = get_hasta(ss, ':');
71                 Persona* pp = susanita.get_persona(nombre);
72                 if (!pp)
73                 {
74                         pp = new Persona(nombre, sexo, cap);
75                         susanita.add_persona(pp);
76                 }
77
78                 int count = 0;
79                 while (ss)
80                 {
81                         std::string nombre = get_hasta(ss, ',');
82                         nombre = strip(nombre);
83                         if (nombre.empty()) {
84                                 continue;
85                         }
86                         Persona* ppp = susanita.get_persona(nombre);
87                         if (!ppp)
88                         {
89                                 ppp = new Persona(nombre, opuesto, cap);
90                                 susanita.add_persona(ppp);
91                         }
92                         pp->prefs.push_back(ppp);
93                         pp->prefs_hash[ppp->nombre] = count;
94                         count++;
95                 }
96         }
97         return true;
98 }
99
100 void
101 Parser::
102 output() const
103 {
104         for (Susanita::personas_type::const_iterator ih
105                         = susanita.hombres.begin();
106                         ih != susanita.hombres.end(); ++ih)
107         {
108                 Persona& h = **ih;
109                 assert(h.estado == Persona::COMPROMETIDO);
110                 std::cout << h.nombre << ", " << h.pareja->nombre << "\n";
111         }
112         std::cout << "\n";
113         for (Susanita::personas_type::const_iterator im
114                         = susanita.mujeres.begin();
115                         im != susanita.mujeres.end(); ++im)
116         {
117                 Persona& m = **im;
118                 assert(m.estado == Persona::COMPROMETIDO);
119                 std::cout << m.nombre << ", " << m.pareja->nombre << "\n";
120         }
121 }
122
123 /// Hack medio feo para obtener el N del problema
124 Susanita::size_type
125 Parser::
126 get_n(const std::string& filename)
127 {
128         std::ifstream f(filename.c_str());
129         if (!f)
130                 return 0;
131         std::string l;
132         if (!std::getline(f, l))
133                 return 0;
134         std::istringstream ss(strip(l));
135         // descartamos el nombre
136         get_hasta(ss, ':');
137         // contamos personas en la lista
138         Susanita::size_type count = 0;
139         while (ss)
140         {
141                 if (!strip(get_hasta(ss, ',')).empty())
142                         ++count;
143         }
144         return count;
145 }
146