From: Leandro Lucarella Date: Mon, 29 Sep 2003 04:33:51 +0000 (+0000) Subject: - Bugfixes. X-Git-Tag: svn_import~6 X-Git-Url: https://git.llucax.com/z.facultad/75.42/string.git/commitdiff_plain/6433cf237a213c6ba195e534da110733de9b4716 - Bugfixes. - Se agrega la funcionalidad para convertir de un string a otro. - Se hace la función quicksort. --- diff --git a/Makefile b/Makefile index 636d4e2..08ee0b6 100644 --- a/Makefile +++ b/Makefile @@ -28,40 +28,26 @@ all: $(TARGETS) # 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) diff --git a/ascii.cpp b/ascii.cpp index 1864fb8..8687cdd 100644 --- a/ascii.cpp +++ b/ascii.cpp @@ -38,7 +38,7 @@ Ascii::~Ascii(void) { #endif } -bool Ascii::is_endl(void) { +bool Ascii::is_endl(void) const { #ifdef DEBUG std::cerr << "En Ascii::is_endl()." << std::endl; #endif @@ -54,14 +54,14 @@ Ascii& Ascii::operator=(const Ascii& ascii) { 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 diff --git a/ascii.h b/ascii.h index a2cb48c..05316e3 100644 --- a/ascii.h +++ b/ascii.h @@ -42,16 +42,16 @@ class Ascii { 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; diff --git a/quicksort.h b/quicksort.h new file mode 100644 index 0000000..8326c72 --- /dev/null +++ b/quicksort.h @@ -0,0 +1,59 @@ +/* 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 + * 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 +#include +#include + +/// 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 +/// 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 diff --git a/unicode.cpp b/unicode.cpp index 127754b..398f82c 100644 --- a/unicode.cpp +++ b/unicode.cpp @@ -37,12 +37,12 @@ Unicode::~Unicode(void) { std::cerr << "En destructor de Unicode." << std::endl; #endif } -#include -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(caracter) == '\n') || (static_cast(caracter >> 8) == '\n'); } @@ -55,14 +55,22 @@ Unicode& Unicode::operator=(const Unicode& unicode) { 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 diff --git a/unicode.h b/unicode.h index 1dcdc87..be95a54 100644 --- a/unicode.h +++ b/unicode.h @@ -49,16 +49,19 @@ class Unicode { * 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; diff --git a/universalstring.cpp b/universalstring.cpp index 5704ce6..245eac6 100644 --- a/universalstring.cpp +++ b/universalstring.cpp @@ -14,27 +14,50 @@ * $Id$ */ -#include #include "ascii.h" #include "unicode.h" #include "universalstring.h" -#include +#include "quicksort.h" +#include +#include using namespace std; int main(void) { // Ascii. - UniversalString sa("Hola mundo"); - cout << sa << endl; + UniversalString< Ascii > sa("Hola mundo"); +// cout << sa << endl; cin >> sa; cout << sa << endl; - +/* // Unicode. - UniversalString 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; } diff --git a/universalstring.h b/universalstring.h index 4ec4d56..44fb64d 100644 --- a/universalstring.h +++ b/universalstring.h @@ -27,11 +27,11 @@ #endif /// String Universal. -template +template < class T > class UniversalString { /// Cadena de caracteres. - std::vector string; + std::vector< T > string; public: @@ -45,12 +45,15 @@ class UniversalString { /// 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]); } @@ -62,6 +65,7 @@ class UniversalString { std::cerr << "En constructor de copia de UniversalString." << std::endl; #endif + string = str.string; } /// Destructor. @@ -76,10 +80,31 @@ class UniversalString { #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 @@ -96,31 +121,33 @@ class UniversalString { 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& 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(out, "")); + std::ostream_iterator< T >(out, "")); return out; } /// Captura desde un stream de entrada. friend std::istream& operator>>(std::istream& in, - UniversalString& 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()) {