- Se agrega la funcionalidad para convertir de un string a otro.
- Se hace la función quicksort.
# Pruebas.
tests: $(TESTS)
- ./dllist_test
-dllist_test: dllist.o
+ascii.o: ascii.cpp ascii.h
-tp3: dllist.o figura.o rectangulo.o cuadrado.o linea.o circulo.o dibujo.o
+unicode.o: unicode.cpp unicode.h
-dllist.o: dllist.cpp dllist.h
+#quicksort.o: quicksort.cpp quicksort.h
-figura.o: figura.cpp figura.h punto.h
+#universalstring.o: universalstring.h universalstring.cpp
-linea.o: figura.o linea.cpp linea.h
+universalstring: ascii.o unicode.o universalstring.cpp
-circulo.o: figura.o circulo.cpp circulo.h
-
-rectangulo.o: figura.o rectangulo.cpp rectangulo.h
-
-cuadrado.o: rectangulo.o cuadrado.cpp cuadrado.h
-
-dibujo.o: dllist.o figura.o dibujo.cpp dibujo.h
-
-
-# Preety-printing del código fuente.
-corrida.txt: tp3
- @./tp3 > corrida.txt
# Regla para borrar.
clean:
@echo "Limpiando..."
- @rm -fR $(TARGETS) *.o core tp2 corrida_*.txt html latex* *.ps
+ @rm -fR $(TARGETS) *.o core html latex* *.ps
# Preety-printing del código fuente.
-FUENTES=dllist.h dllist.cpp punto.h figura.h figura.cpp rectangulo.h \
- rectangulo.cpp cuadrado.h cuadrado.cpp linea.h linea.cpp circulo.h \
- circulo.cpp dibujo.h dibujo.cpp tp3.cpp
+FUENTES=ascii.h ascii.cpp unicode.h unicode.cpp universalstring.h \
+ quicksort.h quicksort.cpp
code.ps: $(FUENTES)
@enscript -j -Ecpp -U2 -C --fancy-header=squeeze --color -pcode.ps \
$(FUENTES)
#endif
}
-bool Ascii::is_endl(void) {
+bool Ascii::is_endl(void) const {
#ifdef DEBUG
std::cerr << "En Ascii::is_endl()." << std::endl;
#endif
return *this;
}
-bool Ascii::operator<(const Ascii& ascii) {
+bool Ascii::operator<(const Ascii& ascii) const {
#ifdef DEBUG
std::cerr << "En operator< de Ascii." << std::endl;
#endif
return caracter < ascii.caracter;
}
-bool Ascii::operator==(const Ascii& ascii) {
+bool Ascii::operator==(const Ascii& ascii) const {
#ifdef DEBUG
std::cerr << "En operator== de Ascii." << std::endl;
#endif
virtual ~Ascii(void);
/// Indica si el caracter es de fin de línea.
- bool is_endl(void);
+ bool is_endl(void) const;
/// Asignación de una instancia a otra.
Ascii& operator=(const Ascii& ascii);
/// Comparación por menor de dos instancias.
- bool operator<(const Ascii& ascii);
+ bool operator<(const Ascii& ascii) const;
/// Comparación por igual de dos instancias.
- bool operator==(const Ascii& ascii);
+ bool operator==(const Ascii& ascii) const;
/// Cast a char.
operator char(void) const;
--- /dev/null
+/* vim: set et sts=4 sw=4 fdm=marker fmr={,} fdn=1 fo+=t tw=80:
+ *
+ * Taller de Programación (75.42).
+ *
+ * Ejercicio Número 4:
+ * Ordena texto ASCII o Unicode.
+ *
+ * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
+ * Puede copiar, modificar y distribuir este programa bajo los términos de
+ * la licencia GPL (http://www.gnu.org/).
+ *
+ * Creado: Mon Sep 22 21:00:15 ART 2003
+ *
+ * $Id$
+ */
+
+#ifndef QUICKSORT_H
+#define QUICKSORT_H
+
+#include <cstdlib>
+#include <vector>
+#include <cmath>
+
+/// Intercambia 2 índices del vector.
+template < class T >
+void swap(std::vector< T >& v, int i, int j) {
+ T tmp = v[i];
+ v[i] = v[j];
+ v[j] = tmp;
+}
+#include <iostream>
+/// Genera un índice al azar.
+int rnd(int i, int j) {
+ return i + rand() % (j-i+1);
+}
+
+/// Algoritmo de ordenamiento generico para ordenar un vector.
+template < class T >
+void quicksort(std::vector< T >& v, int left, int right) {
+ // Asigno como último al de la izquierda.
+ int last = left;
+ // Si los extremos se juntan, termina.
+ if (left >= right) {
+ return;
+ }
+ // Intercambia.
+ swap(v, left, rnd(left, right));
+ for (int i = left + 1; i <= right; i++) {
+ if (v[i] < v[left]) {
+ swap(v, ++last, i);
+ }
+ }
+ swap(v, left, last);
+ // Llama recursivamente para los fragmentos.
+ quicksort(v, left, last - 1);
+ quicksort(v, last + 1, right);
+}
+
+#endif // QUICKSORT_H
std::cerr << "En destructor de Unicode." << std::endl;
#endif
}
-#include <iostream>
-bool Unicode::is_endl(void) {
+
+bool Unicode::is_endl(void) const {
#ifdef DEBUG
std::cerr << "En Unicode::is_endl()." << std::endl;
#endif
- // Si los últimos 8 bits son 0xA = 10 = '\n' devuelve true.
+ // Si los primeros o últimos 8 bits son 0xA = 10 = '\n' devuelve true.
return (static_cast<char>(caracter) == '\n')
|| (static_cast<char>(caracter >> 8) == '\n');
}
return *this;
}
-bool Unicode::operator<(const Unicode& unicode) {
+Unicode& Unicode::operator=(short c) {
+#ifdef DEBUG
+ std::cerr << "En operator= de Unicode (short)." << std::endl;
+#endif
+ caracter = c;
+ return *this;
+}
+
+bool Unicode::operator<(const Unicode& unicode) const {
#ifdef DEBUG
std::cerr << "En operator< de Unicode." << std::endl;
#endif
return caracter < unicode.caracter;
}
-bool Unicode::operator==(const Unicode& unicode) {
+bool Unicode::operator==(const Unicode& unicode) const {
#ifdef DEBUG
std::cerr << "En operator== de Unicode." << std::endl;
#endif
* andar ya que el fin de línea se compone de 2 caracteres: 0xDA, por lo
* tanto termina en 0xA y debería ser considerado fin de línea.
*/
- bool is_endl(void);
+ bool is_endl(void) const;
/// Asignación de una instancia a otra.
Unicode& operator=(const Unicode& unicode);
+ /// Asignación de un short.
+ Unicode& operator=(short c);
+
/// Comparación por menor de dos instancias.
- bool operator<(const Unicode& unicode);
+ bool operator<(const Unicode& unicode) const;
/// Comparación por igual de dos instancias.
- bool operator==(const Unicode& unicode);
+ bool operator==(const Unicode& unicode) const;
/// Cast a char.
operator char(void) const;
* $Id$
*/
-#include <iostream>
#include "ascii.h"
#include "unicode.h"
#include "universalstring.h"
-#include <algorithm>
+#include "quicksort.h"
+#include <iostream>
+#include <vector>
using namespace std;
int main(void) {
// Ascii.
- UniversalString<Ascii> sa("Hola mundo");
- cout << sa << endl;
+ UniversalString< Ascii > sa("Hola mundo");
+// cout << sa << endl;
cin >> sa;
cout << sa << endl;
-
+/*
// Unicode.
- UniversalString<Unicode> su("Hola mundo");
+ UniversalString< Unicode > su("Chau mundo");
cout << su << endl;
cin >> su;
cout << su << endl;
+
+ // Conversión.
+ sa = su;
+ cout << su << endl;
+*/
+ // Agrego cosas al vector para ordenar.
+ vector< UniversalString< Ascii > > v;
+ v.push_back(sa);
+ v.push_back(UniversalString< Ascii >("Hola mundo!"));
+ v.push_back(UniversalString< Ascii >("Chau mundo!"));
+ // Imprimo.
+ cout << "Sin ordenar (" << v.size() << "):" << endl;
+ for (int i = 0; i < v.size(); i++) {
+ cout << v[i] << endl;
+ }
+ // Ordeno.
+ quicksort(v, 0, 2);
+ // Imprimo.
+ cout << "Ordenado:" << endl;
+ copy(v.begin(), v.end(), ostream_iterator< UniversalString< Ascii > >(cout,
+ "\n"));
+
return 0;
}
#endif
/// String Universal.
-template <class T>
+template < class T >
class UniversalString {
/// Cadena de caracteres.
- std::vector<T> string;
+ std::vector< T > string;
public:
/// Constructor a partir de un string C.
UniversalString(const char* str) {
#ifdef DEBUG
- std::cerr << "En constructor de UniversalString a partir de string C."
+ std::cerr << "En constructor de UniversalString desde string C."
<< std::endl;
#endif
int len = strlen(str);
+ // Limpio cadena de caracteres anterior.
string.clear();
+ // Reservo nuevo espacio.
string.reserve(len);
+ // Agrego cada caracter.
for (int i = 0; i < len; i++) {
string.push_back(str[i]);
}
std::cerr << "En constructor de copia de UniversalString."
<< std::endl;
#endif
+ string = str.string;
}
/// Destructor.
#ifdef DEBUG
std::cerr << "En operator= de UniversalString." << std::endl;
#endif
+ // Asigno la cadena de caracteres del string str.
string = str.string;
return *this;
}
+ /// Asignación de una instancia a otra de distinto tipo.
+ template < class T2 >
+ UniversalString& operator=(const UniversalString< T2 >& str) {
+#ifdef DEBUG
+ std::cerr << "En operator= de UniversalString de tipos distintos."
+ << std::endl;
+#endif
+ // Obtengo un vector con los caracteres del string str.
+ std::vector< T2 > v = str.to_vector();
+ // Limpio mi cadena de caracteres.
+ string.clear();
+ // Reservo el nuevo espacio para mi cadena.
+ string.reserve(v.size());
+ // Voy agregando caracter a caracter.
+ for (size_t i = 0; i < v.size(); i++) {
+ string.push_back(T(v[i]));
+ }
+ return *this;
+ }
+
/// Comparación por menor de dos instancias.
bool operator<(const UniversalString& str) {
#ifdef DEBUG
return string == str.string;
}
- /// Cast a string C.
- //operator char*(void);
+ /// Devuelve un vector de caracteres T.
+ std::vector< T > to_vector(void) const {
+ return string;
+ }
/// Volcado a un stream de salida.
friend std::ostream& operator<<(std::ostream& out,
- const UniversalString<T>& str) {
+ const UniversalString< T >& str) {
#ifdef DEBUG
std::cerr << "En operator<< de UniversalString." << std::endl;
#endif
// Copio el vector de caracteres al stream de salida.
std::copy(str.string.begin(), str.string.end(),
- std::ostream_iterator<T>(out, ""));
+ std::ostream_iterator< T >(out, ""));
return out;
}
/// Captura desde un stream de entrada.
friend std::istream& operator>>(std::istream& in,
- UniversalString<T>& str) {
+ UniversalString< T >& str) {
#ifdef DEBUG
std::cerr << "En operator>> de UniversalString." << std::endl;
#endif
// Limpio la cadena actual.
str.string.clear();
- T c;
// Obtengo primer caracter, incluyendo espacios.
+ T c;
in >> std::noskipws >> c;
// Mientras que no sea el fin de línea, sigo leyendo caracteres.
while (!c.is_endl()) {