Problema con el metodo BubbleSort

Iniciado por Jesusinfo, 1 Octubre 2016, 18:18 PM

0 Miembros y 2 Visitantes están viendo este tema.

Jesusinfo

Buenas amigos, tengo un ligero pero tedioso problema con esta función, me compila el programa pero añade valores que no están en el vector que quiero ordenar. Me ordena ciertos valores e introduce valores que no coloque, de manera ordenada pero no son los valores verdaderos. espero haberme explicado lo suficiente, espero su ayuda gracias.

aqui el codigo que estoy usando, tengo la sospecha que el problema tiene que ser en la operacion de desplazamiento 5*posicion+elciclo.

:-(

Código (cpp) [Seleccionar]
int metodoburbuja (int notas[],int pos){

int i,j,aux;
pos=pos-1;
for(int x=0;x<5;x++){
for(j=0;j<5;j++){
if(notas[5*pos+j]>notas[5*pos+j+1]){
aux=notas[5*pos+j];
notas[5*pos+j]=notas[5*pos+j+1];
notas[5*pos+j+1]=aux;
}
}
}
cout<<"El estudiante "<<pos<<" tiene sus notas ordenadas de esta manera"<<endl;
for(int x=0;x<5;x++){
cout<<"NOTA "<<x+1<<" : "<<notas[5*pos+x]<<endl;
}
system("pause");
}

engel lex

muestra el codigo que pasas puede que estés armando un offset incorrecto
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Jesusinfo

Este es el código completo, no hallo el error

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

void llenar (int notas [], string nombres[]);
void imprimir (int notas [], string nombres[]);
int insertar(int notas[]);
int buscar(int b,int notas[]);
int borrar(int pos,int notas[]);
int metodoburbuja (int notas[],int pos);
int menu ();

int num;
int asignatura=5;
string nombres[100];
int posicionesEstudiante=0;
//Funcion que indica la n cantidad de estudiantes y sus notas ----------------------------

void llenar (int notas [], string nombres[]){
system("cls");
cout<<"INDIQUE EL NUMERO DE ESTUDIANTES A UTILIZAR EN EL PROGRAMA: "<<endl<<endl;
cin>>num;
cout<<endl;
for(int i=0; i<=num-1; i++){
cout<<"\nDame el primer nombre del estudiante "<<i+1<<endl;
cin>>nombres[posicionesEstudiante];
cout<<"ESTUDIANTE "<<i+1<<endl;
for (int x=0; x<asignatura; x++){
cout<<"\nNOTA "<<x+1<<": ";
cin>>notas[5*i+x];
}
posicionesEstudiante++;
cout<<endl<<endl;
}
system ("pause");
}

//Funcion para imprimir la n cantidad de estudiantes junto a sus notas ----------------------------
void imprimir (int notas [], string nombres[]){
system("cls");
cout<<"LOS ESTUDIANTES Y SUS NOTAS\n"<<endl;
for(int i=0; i<=num-1; i++){
cout<<nombres[i]<<" EL ESTUDIANTE "<<i+1<<endl<<endl;
// cout<<estudiantes[i]<<endl<<endl;

for (int x=0; x<asignatura; x++){
cout<<"NOTA "<<x+1<<" = "<<notas[5*i+x]<<endl;
}
cout<<endl;
}
system ("pause");
}
 
//Funcion para insertar mas estudiantes-------------------------------------------------
int insertar(int notas[]){
      system("cls");
cout<<"INGRESE LAS NOTAS DEL NUEVO ESTUDIANTE: \n";
        for (int i=0; i<asignatura; i++){
       
        cout<<"\nNOTA "<<i+1<<" : ";
        cin>> notas[5*num+i];
    }
    cout<<endl<<endl;
num++;
        }   
       
//Funcion de Buscar un estudiante con sus 5 notas-----------------------------------------------   
int buscar(int b,int notas[]){
system("cls");
        int i=0, encontrado=0;
        while(i < num && encontrado == 0){
                if(b == i+1){
                     encontrado = 1;
                     }
                     else{
                          i++;
                          }
                }
                if(encontrado == 1){
                     cout<<"EL ESTUDIANTE " << b << " TIENE LAS SIGUIENTES NOTAS: " <<endl<<endl;
                     for (int x=0; x<asignatura; x++){
cout<<"NOTA "<<x+1<<"  =  "<<notas[5*i+x]<<endl;
}
cout<<endl;
}
                     else{
                          cout<<"EL ESTUDIANTE [" << b <<"] NO FUE ENCONTRADO\n\nINTENTE DE NUEVO...\n"<<endl;
                          }
    system("pause");
        }

int borrar(int pos,int notas[]){
system("cls");
        int i = pos -1;
               
               
              for (int x=0; x<asignatura; x++){
              notas[5*i+x]=0/* Nota vacia */;
             
             
     
  }
}

//------------------METODO DE ORDENAMIENTO----------------------

int metodoburbuja (int notas[],int pos){

int i,j,aux;
pos=pos-1;
for(int x=0;x<5;x++){
for(j=0;j<5;j++){
if(notas[5*pos+j]>notas[5*pos+j+1]){
aux=notas[5*pos+j];
notas[5*pos+j]=notas[5*pos+j+1];
notas[5*pos+j+1]=aux;
}
}
}
cout<<"El estudiante "<<pos<<" tiene sus notas ordenadas de esta manera"<<endl;
for(int x=0;x<5;x++){
cout<<"NOTA "<<x+1<<" : "<<notas[5*pos+x]<<endl;
}
system("pause");
}

 

//Menu -------------------------------------------------------------
int menu (){
system("cls");
int opc;
cout<<"MENU DEL PROGRAMA\n-----------------------------------------------\n\n[1] INGRESAR EL NUMERO DE ESTUDIANTES\n\n[2] VISUALIZAR LOS ESTUDIANTES JUNTO A SUS NOTAS\n\n[3] INSERTAR UN NUEVO ESTUDIANTE\n\n[4] BUSCAR LAS NOTAS DE UN ESTUDIANTE\n\n[5] BORRAR O VACIAR LAS NOTAS DE UN ESTUDIANTE\n\n[6] SALIR DEL PROGRAMA\n"<<endl;
cin>>opc;
cout<<"\n";
if(opc>7){
cout<<"LA OPCION ["<<opc<<"] NO EXISTE\n\n"<<endl;
system ("pause");
}

return opc;
}

int main(){

int estudiantes[100];
int notas[500];
int opc,buscado, posicion;
do{
opc=menu();
switch (opc){
case 1:
llenar(notas,nombres);
break;

case 2:
imprimir(notas, nombres);
break;

case 3:
insertar(notas);
break;

case 4:
system("cls");
cout<<"INDICA EL ESTUDIANTE QUE DESEAS BUSCAR: "<<endl<<endl;
cin>>buscado;
buscar(buscado, notas);
break;

case 5:
system("cls");
cout<<"INDIQUE EL ESTUDIANTE QUE DESEA BORRAR/VACIAR SUS NOTAS: ";
cin>>posicion;
cout<<endl;
borrar(posicion,notas);
break;

case 6:
cout<<"Que estudiante deseas que sus notas sean ordenadas: "<<endl;
cin>>posicion;
metodoburbuja (notas, posicion);
break;

case 7:
system("cls");
cout<<"\n\nGRACIAS POR USAR NUESTRO PROGRAMA :)\n"<<endl;
break;
}
}
while (opc !=7);
system ("pause");
}





4dr14n31t0r

#3
En el metodo insertar, insertas el numero del nuevo alumno y sus notas, pero no su nombre, lo que podra suponer un problema al llamar despues al metodo imprimir, el cual imprime el nombre de los alumnos junto a sus notas. En el metodo borrar pasa mas de lo mismo.

Cada vez que haces un bucle como este:
Código (cpp) [Seleccionar]
for(int x = 0; x < asignatura; x++) accedes al array de notas poniendo
Código (cpp) [Seleccionar]
notas[5*i+x]Es de suponer que ese 5 vale 5 porque es lo que vale asignaturas. Si es asi, ¿Por que no pones directamente asignaturas otra vez? algo como esto:
Código (cpp) [Seleccionar]
notas[asignaturas*i+x]De esta forma, si modificas el valor de la variable asignaturas el programa no fallará.

Si has visto los punteros y la relaccion que existe entre estos y los arrays (Sospecho que no), deberias de entender porque cuando llamas al metodo burbuja y luego al metodo imprimir, estos aparecen modificados. Comento esto porque supongo que el metodo metodoburbuja solo te deberia mostrar los valores ordenados y no dejarlos asi.
En cualquier caso lo que haces en el metodo burbuja es intercambiar 2 valores del array consecutivos cuando el que esta en una posicion menor tiene un valor mayor que el que esta en la posicion siguiente. Utilizas un solo array para guardar TODAS las notas de TODOS los alumnos, de modo que si la ultima nota de un alumno es mayor que la primera nota del alumno siguiente, los valores se modifican resultando en que la primera nota del alumno siguiente sera siempre la mayor de las notas del alumno anterior.

Jesusinfo

Citar4dr14n31t0r

Pues entendi en su mayoría tu respuesta, pero lo mas importante no lo entendí en realidad, osea la parte del método burbuja. Pues bien ya modifique mi código para que el arreglo string intervenga en todas las funciones y no ocasiones ningún problema a la hora de imprimir, insertar etc, al igual que la variable asignatura. eso lo entendí perfecto. Pero ahora en el método burbuja entiendo que quieres decir con que si la ultima nota del estudiante 1 es mayor a la primera nota del estudiante dos, cambiaría y por ende me alteraría el orden que quiero asignar en mi programa. Pero para eso no seria la operación de desplazamiento:
asignatura*pos+losnumerosdevueltas. osea que me recorra 5 veces la notas de dicha posición que no se salga de esas 5 vueltas, es lo que no logro entender porque altera ciertos valores de las notas si le estoy suministrando la posición desde donde debe de arrancar el ordenamiento burbuja y indicándole que son 5 elementos a ordenar.

dato000

Cita de: 4dr14n31t0r en  2 Octubre 2016, 02:31 AM
Si has visto los punteros y la relaccion que existe entre estos y los arrays (Sospecho que no), deberias de entender porque cuando llamas al metodo burbuja y luego al metodo imprimir, estos aparecen modificados. Comento esto porque supongo que el metodo metodoburbuja solo te deberia mostrar los valores ordenados y no dejarlos asi

Eso depende más del negocio, literalmente el ordenamiento de burbuja debe reordenar el arreglo original, usando un arreglo auxiliar donde se almacena temporalmente cada valor de la posición a modificar comparandola con la siguiente posición del arreglo, pero esta a criterio del desarrollador si se muestra el arreglo ordenado o el auxiliar, en ambos casos, es correcta la forma de la metodología.

Por otra parte, creo que el código solamente funcionaria para un solo estudiante, pues al estar definiendo un arreglo de caracteres, solo almacenaria una cadena que equivaldria a solo un solo estudiante.

Y lo de notas[5*i+x]; no lo termino de entender, porque tiene que ser una posición 5, que pasa si el estudiante es 0 y luego uno, se desperdiciarian 3 posiciones del arreglo y practicamente quedaria en limbo en el ordenamiento de burbuja, pues este solo compara con las posiciones inmedatamente siguientes.

un ejemplo:

estudiante 1: camilo
notas[5*i+x] ---> i=0; x=0;  == notas[0]
notas[5*i+x] ---> i=0; x=1;  == notas[0]
notas[5*i+x] ---> i=1; x=0;  == notas[0]
notas[5*i+x] ---> i=0; x=1;  == notas[5]

WTF!!! cuando va a ubicarse en las posiciones 1,2,3 y 4??? lo mismo sucederia con las demás. Creo deberia replantearse primero la estructura de las notas para un solo estudiante y ejectuar el ordenamiento de las notas de solo un estudiante, y luego implementar una escalabilidad para varios estudiantes después de tener claro el proceso de inserción, guardado, impresión y ordenamiento de cada estudiante y sus notas.

Usar un arreglo de string, bueno, es algo raro, a mi ni siquiera me esta funcionando en linux el primer paso, loco no??



Jesusinfo

Cita de: dato000 en  2 Octubre 2016, 18:35 PM
Y lo de notas[5*i+x]; no lo termino de entender, porque tiene que ser una posición 5, que pasa si el estudiante es 0 y luego uno, se desperdiciarian 3 posiciones del arreglo y practicamente quedaria en limbo en el ordenamiento de burbuja, pues este solo compara con las posiciones inmedatamente siguientes.

un ejemplo:

estudiante 1: camilo
notas[5*i+x] ---> i=0; x=0;  == notas[0]
notas[5*i+x] ---> i=0; x=1;  == notas[0]
notas[5*i+x] ---> i=1; x=0;  == notas[0]
notas[5*i+x] ---> i=0; x=1;  == notas[5]


No entiendo esa parte, ya que planteas que el estudiante camilo saltaría a otro estudiante cuando dices notas[5*i+x] ---> i=1; x=0;  == notas[0]
ya que i representa los estudiantes, y x el desplazamiento de notas o las vueltas que hará, y 5 el numero de notas que tiene el estudiante. En este caso de la forma que planteo el programa es que por estudiante tendrá 5 notas y ya. Ahora mi problema y mi duda es que si es posible que en un vector que almacena todas las notas puedo ordenar cierta cantidad de notas. algo así [ 10 9 8 7 6 5 4 3 2 1 ] ordenado_ciertacantidad [6 7 8 9 10 5 4 3 2 1] no se si me explico lo suficientemente claro  :-(.

4dr14n31t0r

#7
Cita de: Jesusinfo en  2 Octubre 2016, 16:59 PM
Pues entendi en su mayoría tu respuesta, pero lo mas importante no lo entendí en realidad
Perdona si no me explique bien antes.

Veamos, vamos a suponer que en el programa vamos a meter solo a 2 estudiantes.
Entonces el arreglo con las notas tendra una longitud para almacenar 5*2 valores (5 notas para cada alumno).
Entonces el array de los nombres y de las notas te quedara tal que asi:

Array de los alumnos:   [nombre1,                      nombre2]
Array de las notas:     [nota1,nota2,nota3,nota4,nota5,nota6,nota7,nota8,nota9,nota10]


Los espacios solo los he puesto para que veas que las 5 primeras notas del array de notas corresponden al alumno1, y los 5 siguientes a los del alumno2.

Ahora bien, en tu metodo burbuja, por lo que veo haces lo siguiente:
1- Coges el elemento 5*pos+j (que seguramente habrás cambiado a asignaturas*pos+j).
2- Lo comparas con el elemento 5*pos+j+1.
3- Si es mayor intercambias los valores, y si es menor lo dejas tal cual.
4- Repites desde el paso 1 con el siguiente elemento


Bueno pues tu error esta en el paso numero 2, ya que en los arrays que expuse antes:
Array de los alumnos:   [nombre1,                      nombre2]
Array de las notas:     [nota1,nota2,nota3,nota4,nota5,nota6,nota7,nota8,nota9,nota10]


Suponte que la mayor nota del alumno1 es la nota 5. Entoces el metodo deberia dejar la nota 5 intacta en lugar de intercambiarla. Pero suponte que la nota5 del alumno1 es MAYOR que la nota6 del alumno2. Entonces sucede lo siguiente:

5*pos+j == 4
notas[5*pos+j] == nota5

5*pos+j+1 == 5
notas[5*pos+j+1] == nota6

nota5 > nota6 == true


Al ser nota5 mayor que nota6 se intercambian los valores, por lo que el valor mas grande del alumno1 pasa a ser la primera nota del alumno2.
¿Lo ves ahora?

La forma de solucionarlo es muy sencilla. Solo tienes que cambiar el numero de iteraciones del bucle de la variable j. En lugar de
Código (cpp) [Seleccionar]
for(j=0;j<5;j++) pon
Código (cpp) [Seleccionar]
for(j=0;j<4;j++){

El bucle de la variable x tambien deberia ser
Código (cpp) [Seleccionar]
for(x=0;x<4;x++)pero de todos modos da un poco lo mismo, ya que con que lo recorra al menos 4 veces las demas veces que la recorra no hará nada. Si hubieras puesto
Código (cpp) [Seleccionar]
for(x=0;x<200;x++)Tambien funcionaría.

Jesusinfo

Cita de: 4dr14n31t0r en  2 Octubre 2016, 19:59 PM

La forma de solucionarlo es muy sencilla. Solo tienes que cambiar el numero de iteraciones del bucle de la variable j. En lugar de
Código (cpp) [Seleccionar]
for(j=0;j<5;j++) pon
Código (cpp) [Seleccionar]
for(j=0;j<4;j++){

Muchisimas gracias 4dr14n31t0r Tienes razon y me has dando una gran ayuda has entendido mi problema y yo tu explicacion mejor imposible de verdad gracias, capte perfectamente la idea y como funciona, tiene que ser j<5 porque estoy comparando notas[j] con notas[j+1] ese pequeño detalle no lo capte me falta por desarrollar mas la lógica.

Tengo una duda con respecto a la funcion principal al darle limites al vector notas
yo lo tengo asi para que me reconozca sin ningun error todo:
Código (cpp) [Seleccionar]

int main(){

int estudiantes[num];
int notas[500];


pero no quiero darle un valor como limite a mi vector notas ya que en un futuro podria crecer o decrecer, quisiera establecerlo con una variable, y lo he intentado de esta manera:

Código (cpp) [Seleccionar]

int notas[num*asignatura];

me captura todos los estudiante y las notas, pero a la hora de imprimir me salta un error y deja de funcionar el programa. 

El otro que intente fue dejarlo vació  así

Código (cpp) [Seleccionar]

int notas[]={};


Lo reconoce perfecto todos los estudiante y sus notas pero mayormente el estudiante 1 nota 1 le quita un digito o lo cambia  o varias notas a varios estudiantes el punto es que no da la informacion correctapor ejemplo
Estudiante 1 Nota 1= 20. La imprime como Estudiante 1 Nota 1= 2.
Hay una forma de que el vector vaya creciendo a medida de que vayan aumentando los estudiantes?

dato000

Ah creo que ya he captado el funcionamiento de las notas por estudiantes, yo lo estaba viendo como matrices, hay que darle otro enfoque.

Creeria que en el sentido de mejorar el entendimiento de código, lo mejor seria encapsular esas variables de las posiciones de los alumnos.

notas[5*num+i]; ==> notas[(5*num) + 1], en donde podrias añadir un comentario respecto a esa parte que resulta un poco enredada de entender salvo que se entienda el concepto de lo que debe realizarse, como es en el caso, conociendo al estudiante en una determinada posición, equivaldria a ubicar sus notas en el larguisimo arreglo de notas.

otra cosa, tu menú presenta inconsistencias, lo arregle un poco, aunque esta modificado para ejecutarse en linux, tendrias que cambiar las sentencias de system.

Código (cpp) [Seleccionar]

//INTERFAZ DE USUARIO
int menu (){
system("clear");
int opc;

cout<<"MENU DEL PROGRAMA\n----------------------------------------------- " << endl;
cout<<"[1] INGRESAR EL NUMERO DE ESTUDIANTES" << endl;
cout<<"[2] VISUALIZAR LOS ESTUDIANTES JUNTO A SUS NOTAS" << endl;
cout<<"[3] INSERTAR UN NUEVO ESTUDIANTE" << endl;
cout<<"[4] BUSCAR LAS NOTAS DE UN ESTUDIANTE" << endl;
cout<<"[5] BORRAR O VACIAR LAS NOTAS DE UN ESTUDIANTE" << endl;
cout<<"[6] ORDENAMIENTO BURBUJA" << endl;
cout<<"[7] SALIR DEL PROGRAMA\n" << endl;

    cout << "DIGITE SU OPCION:  ";
cin>>opc;
cout<<"\n";
if(opc>7){
        cout<<"LA OPCION ["<<opc<<"] NO EXISTE\n\n"<<endl;
        cin.get();
    }

return opc;
}

// MENU PRINCIPAL OPCION DE USUARIO
int main(){

    int estudiantes[100];
    int notas[500];
    int opc,buscado, posicion;
    do{
        opc=menu();
        switch (opc){
            case 1:
                llenar(notas, nombreEstudiante);
                break;

            case 2:
                imprimir(notas, nombreEstudiante);
                break;

            case 3:
                insertar(notas);
                break;

            case 4:
                system("clear");
                cout<<"INDICA EL ESTUDIANTE QUE DESEAS BUSCAR: "<<endl<<endl;
                cin>>buscado;
                buscar(buscado, notas);
                break;

            case 5:
                system("clear");
                cout<<"INDIQUE EL ESTUDIANTE QUE DESEA BORRAR/VACIAR SUS NOTAS: ";
                cin>>posicion;
                cout<<endl;
                borrar(posicion,notas);
                break;

            case 6:
                cout<<"Que estudiante deseas que sus notas sean ordenadas: "<<endl;
                cin>>posicion;
                metodoburbuja (notas, posicion);
                break;

            case 7:
                system("clear");
                cout<<"\n\nGRACIAS POR USAR NUESTRO PROGRAMA :)\n"<<endl;
                break;
        }
    }
    while (opc !=7);
    cin.get();
}


Estoy intentado correr el código correctamente para un solo estudiante en linux, ya que se presentan inconsistencias, una vez las tenga las voy a publicar, puede que ayude un poco.