Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Rockmore en 16 Marzo 2011, 19:34 pm



Título: [C++] Reordenar vector dinámico de objetos
Publicado por: Rockmore en 16 Marzo 2011, 19:34 pm
Saludos. Liado ando con un gestor de agenda, en el que he de reordenar por nombre los contactos cada vez que añado uno nuevo. Por supuesto, pensé en la burbuja, pero, a pesar de que compila sin problemas, no reordena nada. He aquí mi código:
Código
  1. //Clase Agenda
  2. class Agenda{
  3. private:
  4.    Contacto *lista;
  5.    int N;
  6. public:
  7.    //Constructor por defecto
  8.    Agenda(){
  9.        N=0;
  10.        lista=NULL;
  11.        return;
  12.    }
  13.    //Destructor
  14.    ~Agenda(){
  15.        if(lista){
  16.            delete[]lista;
  17.        }
  18.    }
  19.    //Metodo aniadir contacto
  20.    void NuevoContacto(void){
  21.        //Creacion vector Contacto auxiliar
  22.        Contacto *aux=new Contacto[N+1];
  23.        //Recoleccion de datos anteriores
  24.        for(int i=0;i<N;i++){
  25.            aux[i]=lista[i];
  26.        }
  27.        //Peticion de dato nuevo
  28.        cin>>aux[N];
  29.        cin>>aux[N].fnac;
  30.        cin>>aux[N].dir;
  31.        //Eliminacion de vector Contacto obsoleto
  32.        if(lista!=NULL){
  33.            delete[]lista;
  34.        }
  35.        //Recreacion de vector Contacto util
  36.        lista=aux;
  37.        N++;
  38.        Ordenar(lista,N);
  39.        return;
  40.    }
  41.  
  42. //.........
  43.  
  44.    //Metodo reordenacion de contactos
  45.    void Ordenar(Contacto listado[], int n){
  46.        Contacto aux;
  47.        bool centinela;
  48.        for(int i=0;i<n&&centinela==true;i++){
  49.            centinela=false;
  50.            for(int j=0;j<n;j++){
  51.                if(listado[j-1].VerNombre()>listado[j].VerNombre()){
  52.                    aux=listado[j-1];
  53.                    listado[j-1]=listado[j];
  54.                    listado[j]=aux;
  55.                    centinela=true;
  56.                }
  57.            }
  58.        }
  59.        return;
  60.    }
  61. };
¿Dónde está el fallo?


Título: Re: [C++] Reordenar vector dinámico de objetos
Publicado por: Akai en 16 Marzo 2011, 20:05 pm
Falta código para entender completamente lo que estás haciendo, pero básicamente creo que es esto:
Código
  1. listado[j-1].VerNombre()>listado[j].VerNombre()

No puedes comparar "nombres" de esa forma, C++ es potente, pero no hace magia. Puedes comparar enteros, floats, carácteres, booleanos entre sí, pero no tipos compuestos, estructuras, vectores, u objetos de una clase.

Para tu caso, las cadenas se comparan con strcmp (http://cplusplus.com/reference/clibrary/cstring/strcmp/). Si usas strings (http://cplusplus.com/reference/string/string/), lo puedes hacer con string.compare() (http://cplusplus.com/reference/string/string/compare/).

Opciones:
1)comparas utilizando la función o clase y método dichos arriba.

2) sobrecargas el operador > para tu clase Contacto para que realice la comparación de lo dicho en la opción 1 (si te ves con ánimo, para ampliar te irá bien) o implementarte tu propio método para comparar cadenas(Mejor no te compliques la vida, mira la opción 1).


Título: Re: [C++] Reordenar vector dinámico de objetos
Publicado por: Rockmore en 17 Marzo 2011, 19:05 pm
Bueno, después de darle mil vueltas logré encontrar los dos fallos que había, como siempre, tonterías, pero que hacen que te vuelvas loco.
Para empezar, el símbolo > funciona, el tema es que el booleano centinela no estaba inicializado, por tanto, no entraba en el bucle de ordenación. Por otro lado, el bucle interno empezaba en j=0, cuando debía hacerlo en j=1. El código resultante del método es el siguiente.
Código
  1. //Metodo reordenacion de contactos
  2.    void Ordenar(void){
  3.        Contacto aux;
  4.        bool centinela=true;
  5.        for(int i=0;i<N&&centinela;i++){
  6.            centinela=false;
  7.            for(int j=1;j<N;j++){
  8.                if(lista[j-1].VerNombre()>lista[j].VerNombre()){
  9.                    aux=lista[j];
  10.                    lista[j]=lista[j-1];
  11.                    lista[j-1]=aux;
  12.                    centinela=true;
  13.                }
  14.            }
  15.        }
  16.        return;
  17.    }
  18.  
De todos modos, gracias por el aporte. Lo tendré en cuenta para futuros programas, que se avecinan chungos.  ;)