• Sábado 2 de Agosto de 2014, 08:29

Autor Tema:  Vector compuesto de dos vectores...  (Leído 2489 veces)

ermiguel1979

  • Miembro activo
  • **
  • Mensajes: 45
    • Ver Perfil
Vector compuesto de dos vectores...
« en: Viernes 8 de Enero de 2010, 17:22 »
0

Publicidad 
Buenas tardes a todos. Hoy tengo un (otro) superproblema con un ejercicio que no me sale 'ni palante ni patrás'. El enunciado dice así:

Esctribir un programa al que se le de como entrada dos arrays de enteros ordenados de forma creciente, y devuelva como salida un array ordenado de forma creciente formado por los elementos de las entradas y sin incluir los elementos repetidos.

Bueno, he probado muchas cosas, ninguna con éxito, para intentar que a la vez que almaceno los dos arrays de forma independiente, se guarden en el array conjunto... ese es un problema. El otro es que no se como hacer que se eliminen los elementos repetidos. Ordenarlos de forma creciente se hará con un ordenamiento burbuja (p. ej.) y lo de eliminar los repetidos, con alun tipo de comparación y contador...

El principal obstáculo lo encuentro en almacenas los datos de los dos primeros arrays en el array de salida.
En el código que mando, intento hacerlo con dos bucles for, pero luego me muestra un chorrazo de números de más...

Éste es el código que llevo hecho:
Código: C
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define TAMA 50
  6. #define LONG 100
  7.  
  8. int main (void){    
  9.     int array_a[TAMA];
  10.     int array_b[TAMA];
  11.     int array_c[LONG];
  12.     int a, b;
  13.     int longitud_a, longitud_b, longitud_c;
  14.        
  15.     printf("'Introduzca numero de elementos del array_a (hasta 50)': ");
  16.     scanf("%i", &longitud_a);
  17.     printf("'Introduzca numero de elementos del array_b (hasta 50)': ");
  18.     scanf("%i", &longitud_b);
  19.     longitud_c=longitud_a+longitud_b;
  20.     printf("n");  
  21.     printf("'Introduzca elementos del array_a'n");
  22.     for(a=0; a<longitud_a; a++){
  23.             printf("elemento %i array_a: ", a);
  24.             scanf("%i", &array_a[a]);                  
  25.     }
  26.     printf("n");  
  27.     printf("'Introduzca elementos del array_b'n");
  28.     for(b=0; b<longitud_b; b++){
  29.         printf("elemento %i array_b: ", b);
  30.         scanf("%i", &array_b[b]);
  31.                
  32.     }
  33.     printf("n");  
  34.    
  35.     printf("array_a: ");
  36.     for(a=0; a<longitud_a; a++){
  37.         printf("%i", array_a[a]);              
  38.     }
  39.     printf("n");
  40.     printf("array_b: ");
  41.     for(a=0; a<longitud_b; a++){
  42.         printf("%i", array_b[a]);              
  43.     }
  44.     printf("n");
  45.     /*Aqui intento llenar el array_c con los elementos de los otros dos pero..*/
  46.     for(a=0; a<longitud_a; a++){
  47.         array_c[a]=array_a[a];
  48.     }
  49.     a=a+1; b=0;
  50.     for(b=0; b<longitud_b; b++, a++){
  51.         array_c[a]=array_b[b];
  52.     }
  53.     /*al mostrarlo, no está como debiera*/
  54.     printf("array_c: ");
  55.     for(a=0; a<longitud_c; a++){
  56.         printf("%i", array_c[a]);              
  57.     }
  58.     printf("n");
  59.  
  60.     return 0;
  61. }
  62.  
  63.  


Ojalá podasi orientarme un poco, porque no se como segir.

Gracias. Un saludo!

Miguel.

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #1 en: Sábado 9 de Enero de 2010, 03:49 »
0
Hola ermiguel1979, te dire que vas bien con tu algoritmo solo tienes un error en la linea 49:

Código: C++
  1.  
  2.     a=a+1; b=0;
  3.  
  4.  
1

No necesitas incrementar "a", ya que al salir del ciclo anterior, "a" ya tiene el valor de la siguiente posicion del vector, cuando lo incrementas en esta linea te estas saltando una posicion del vector_c, y esa posicion es probable que contenga basura, por eso al imprimir vector_c te muestra ese valor basura. Tampoco necesitas hacer b = 0 ya que en la siguiente linea en tu ciclo for ya tienes b = 0. Ademas deberias colococar un espacio vacio en tus printf despues del %i de la siguiente manera:

Código: C++
  1.  
  2.         printf("%i ", array_c[a]);              
  3.  
  4.  

para que los numeros no te aparezcan pegados y parezcan que son un mismo numero cuando en realidad son varios numeros.

Ahora, para eliminar los duplicados, una vez que ya tengas ordenado el vector, necesitas un ciclo que recorra todo el vector, comparando cada elemento con el siguiente (array_c == array_c[i+1]), cuando sean iguales, haces un corrimiento de todo el vector hacia adelante (array_c =  array_c[i+1]), mediante otro ciclo, para que elimines el elemento, cuando termines el corrimiento, disminuyes la variable que te guarda el total de elementos de vector_c (o sea si el total de elementos de tu vector es de 10, le quitas 1 para que quede en 9, ya que eliminaste un elemento al hacer el corrimiento) y vuelves a hacer la comparacion desde el principio de cada elemento con el siguiente, asi hasta que no encuentres elementos iguales.

Atento al tamaño del vector, para que al hacer la comparacion no sobrepases sus indices, o sea, si tu vector tiene 10 elementos, no puedes hacer una comparacion del elemento 10 con el 11, ya que el 11 no existe. Si le quitas un elemento es lo mismo, cuidado con pasarte de los indices, en este ejemplo, si quitas 1, te queda 9, entonces ya no puedes compara el elemento 9 con el 10 porque el 10 ya no existe (aunque fisicamente si exsita, pero tu deberas hacer como si no existiera).

Con esas pistas supongo que lo podras terminar.

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

Aragorn_montaraz

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #2 en: Sábado 9 de Enero de 2010, 12:25 »
0
Aprovechando que los vectores array_a y array_b deberian estar ordenados ascendientemente, abria una forma más eficiente de hacerlo que juntar los dos vectores y luego ordenarlos.

Sería ir recorriendo los dos vectores elemento a elemento y eligiendo el menor elemento de los dos, que siempre estará en la primera posición, para colocarlo en el array_c.
Seria algo así:

Código: C
  1.  
  2. int ele;
  3. for(a = 0, b = 0, c = 0; c < longitud_c; c++) {
  4.       if (array_a[a] < array_b[b]) {  //Copiamos el menor elemento.
  5.          array_c[c] = array_a[a];
  6.          ele = array_a[a];
  7.          while (array_a[a] == ele) a++;       //"Eliminamos" ese elemento de a y los repetidos.
  8.       }
  9.       else if (array_a[a] > array_b[b]) {  //Copiamos el menor elemento.
  10.         array_c[c] = array_b[b];
  11.         ele = array_b[b];
  12.         while (array_b[b] == ele) b++;       //"Eliminamos" ese elemento de b y los repetidos.
  13.       }
  14.       else {   //Los dos elementos son iguales. Copiamos uno y eliminamos repetidos de los dos.
  15.        array_c[c] = array_b[b];
  16.        ele = array_b[b];
  17.        while (array_b[b] == ele) b++;
  18.        while (array_a[a] == ele) a++;
  19.     }
  20. }
  21.  
  22.  

Es más dificil de entender, pero mucho más eficiente.

ermiguel1979

  • Miembro activo
  • **
  • Mensajes: 45
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #3 en: Sábado 9 de Enero de 2010, 15:39 »
0
ProfesorX, he corregido lo del contador y he podido seguir con el ejercicio. He almacenado los valores de los dos arrays de entrada en el tercero y lo he ordenado de forma creciente con la "burbuja", pero a la hora de hacer lo que dices de recorrer el vector desplazando los repetidos para ehcarlos fuera, no logro hacerlo.

Lo he solucionado de dos formas: una es mostrando solamente los elementos no repetidos.
Código: C
  1.  
  2. /*Mostrar array_c SIN elementos repetidos (opción 'imprimir')*/
  3.     printf("array_c SIN elementos repetidos: ");  //no modifica array en memoria
  4.     for(a=0; a<longitud_c; a++){
  5.         if(array_c[a]!=array_c[a+1]){
  6.             printf("%i ", array_c[a]);
  7.         }else{
  8.             continue;
  9.         }
  10.     }
  11.     printf("n");
  12.     return 0;
  13. }
  14.  
  15.  

Cosa de no deja de resultarme bastante chapucera...

La otra, es volver a hacerle la "burbuja" al array de salida... tampoco de gusta mucho, pero al menos sí modifica el array en memoria:
Código: C
  1.  
  2. /*Mostrar array_c SIN elementos repetidos (opción 'burbuja')*/
  3.     for(a=0; a<longitud_c; a++){                    
  4.         if(array_c[a]==array_c[a+1]){          
  5.             posicion=a;                        
  6.             for(b=posicion+1; b<longitud_c; b++){  
  7.                 aux=array_c[b+1];                  
  8.                 array_c[b+1]=array_c[b];            
  9.                 array_c[b]=aux;                    
  10.             }                                  
  11.             longitud_c=longitud_c-1;  
  12.         }              
  13.     }
  14.  
  15.  

Que me deja algo más contento, pero no creo que se parezca a lo que comentabas.

Si puedes indicarme algo más sobre esa forma en que dices que puede hacerse...

Gracias ProfesorX :good:

ermiguel1979

  • Miembro activo
  • **
  • Mensajes: 45
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #4 en: Sábado 9 de Enero de 2010, 15:47 »
0
Hola Aragorn_montaraz. Sobre la solución que comentas, he estado trabajando y, aunque no entiendo muy bien como funciona...
... parece tener un problema a la hora de mostrar el vector resultante.

La cosa es que cuando lo muestra, añade basura al quedar sin machacar varias direcciones correspondientes a los elementos repetidos en los arrays de entrada.

Intento solucionarlo con un contador que debería incrementarse en uno cada vez que se guarda un valor en el array de salida. Más tarde, este contador será usado a modo de dimensión del array de salida, a la hora de mostrarlo en pantalla.

El problema está, supongo, en que como no se bien como trabaja el código, no se donde colocar los incrementos del contador.

Te envío el código para ver si puedes decirme dónde irían los incrementos del contador, o de que manera solucionarlo sin él.

Código: C
  1.  
  2. /*Escribir el array_c con los elementos de los arrrays 'a' y 'b'*/  
  3. for(a = 0, b = 0, c = 0; c < longitud_c; c++) {
  4.       if (array_a[a] < array_b[b] && a<longitud_a) {                           //Copiamos el menor elemento.
  5.          array_c[c] = array_a[a];
  6.          ele = array_a[a];
  7.          contador=contador+1;
  8.          while (array_a[a] == ele) a++;                                              //"Eliminamos" ese elemento de a y los repetidos.
  9.       }
  10.       else if (array_a[a] > array_b[b] && b<longitud_b) {                   //Copiamos el menor elemento.
  11.         array_c[c] = array_b[b];
  12.         ele = array_b[b];
  13.         contador=contador+1;
  14.         while (array_b[b] == ele) b++;                                              //"Eliminamos" ese elemento de b y los repetidos.
  15.       }
  16.       else {                                                         //Los dos elementos son iguales. Copiamos uno y eliminamos repetidos de los dos.
  17.        array_c[c] = array_b[b];      
  18.        ele = array_b[b];
  19.        while (array_b[b] == ele) b++;
  20.        while (array_a[a] == ele) a++;
  21.       }      
  22. }
  23.  
  24. printf("%in", contador);
  25. printf("array_c: ");                        //mostrar array_c
  26.       for(a=0; a<=contador+1; a++){
  27.     printf("%i ", array_c[a]);              
  28. }
  29.  
  30.  


Gracias por la ayuda.

Un saludo!

Aragorn_montaraz

  • Nuevo Miembro
  • *
  • Mensajes: 2
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #5 en: Sábado 9 de Enero de 2010, 17:31 »
0
Wolas de nuevo ermiguel1979.

Primero decirte, que el algoritmo que te e puesto antes, solo funciona si los vectores array_a y array_b ya estan ordenados. En el enunciado del problema te dicen que es así, pero si los metes "a mano" debes de asegurarte de que sea así.

Respecto a lo del contador que has añadido, decirte que en realidad no haría falta. En el ejemplo que yo te e puesto, por cada iteración del bucle for,  se almacena un elemento en el array_c, por lo que la variable "c" que se inicializa al principio del bucle a 0, y que se incrementa con cada iteración al acabar el bucle sería el valor del contador que estas buscando.
Si aún así quisieras usar otra variable como contador, la que tu as situado esta bien, solamente te faltaria otro incremento dentro del else.

Una ultima cosa, en algún momento, uno de los vectores a o b se quedarán sin elementos, y el bucle for dejará de funcionar. Tu has intentado paliar esto añadiendo el && a<longitud_a y el && b<longitud_b, pero conforme esta puesto no funcionaría.
La mejor solución es terminar el bucle cuando uno de los vectores se quede sin elementos. Modificando el bucle así:
Código: C
  1.  
  2. for(a = 0, b = 0, c = 0; c < longitud_c && a < longitud_a && b < longitud; c++)
  3.  
  4.  

Y despues del for, como abrá algun vector que aún tenga elementos añadir esto:
Código: C
  1.  
  2. while (b < longitud_b) { array_c[c] = array_b[b]; b++; c++}
  3. while (a < longitud_a) { array_c[c] = array_a[a]; a++; c++}
  4.  
  5.  

De los que siempre se ejecutará solo uno y volcará el vector que aún este lleno.

Espero haber sido de ayuda, no se que nivel tienes, alomejor es un algoritmo muy rebuscado para ti aún, si no te piden que optimizes centraté en la solución que entiendas más.

Un saludo. :hola:

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #6 en: Sábado 9 de Enero de 2010, 22:28 »
0
Bueno, la solucion que te mencionaba antes seria algo como:

Código: C++
  1.  
  2.     b = 0; a = 1;
  3.     while (a < longitud_c)
  4.     {
  5.         while (array_c[b] == array_c[a] && a < longitud_c)
  6.         {
  7.             for (int i = a; i < longitud_c - 1; i++)
  8.             {
  9.                 array_c[i] =  array_c[i+1];
  10.             }
  11.             longitud_c--;
  12.         }
  13.         b++;
  14.         a++;
  15.     }
  16.  
  17.  

Ahora, debo decir que este algoritmo no es muy eficiente, ya que en el peor de los casos, (que los repetidos esten al principio) tienes que recorrer casi todos los elementos del vector.

La solucion que plantea Aragorn_montaraz de ir juntado los dos vectores en unos solo, pero pasando solamente los no repetidos, realmente creo que es mas eficiente, aun cuando su implementacion es mas compleja.

En programacion siempre te encontraras casos asi, ya que casi siempre hay mas de una forma de resolver un mismo problema. La solucion que elijas dependera de que es mas importante para ti, la eficiencia o la simplicidad. Habra casos en que no requieras ser muy eficiente, y te vayas por la solucion mas simple de entender e implementar, otros en que la eficiencia es lo primordial, entonces deberas hacer un esfuerzo para hacerlo mas eficiente. Eso es lo bonito de la programacion, solo eso queria añadir ;)

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

ermiguel1979

  • Miembro activo
  • **
  • Mensajes: 45
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #7 en: Domingo 10 de Enero de 2010, 11:34 »
0
Buenos días Aragorn_montaraz. Como se puede apreciar, mi nivel deja mucho que desear...
...pero que no se diga que no pongo empeño.

He probado lo que dices, aunque no me queda claro dónde hay que poner los "while". Como dices que van despues del "for", los he colocado aquí. Te envío esa parte del código para que me comentes, porque sigue sin funcionar correctamente. También he tenido que retocarlos un poco, porque tal y como los posteaste no hacían nada.

Código: C
  1.  
  2. /*Escribir el array_c con los elementos de los arrrays 'a' y 'b'*/  
  3. for(a = 0, b = 0, c = 0; c<longitud_c && a<longitud_a && b<longitud_b; c++){
  4.       if (array_a[a] < array_b[b]){  //Copiamos el menor elemento.
  5.          array_c[c] = array_a[a];
  6.          ele = array_a[a];        
  7.          while (array_a[a] == ele) a++;       //"Eliminamos" ese elemento de a y los repetidos.
  8.       }
  9.       else if (array_a[a] > array_b[b]){  //Copiamos el menor elemento.
  10.         array_c[c] = array_b[b];
  11.         ele = array_b[b];        
  12.         while (array_b[b] == ele) b++;       //"Eliminamos" ese elemento de b y los repetidos.
  13.       }
  14.       else {   //Los dos elementos son iguales. Copiamos uno y eliminamos repetidos de los dos.
  15.        array_c[c] = array_b[b];      
  16.        ele = array_b[b];
  17.        while (array_b[b] == ele) b++;
  18.        while (array_a[a] == ele) a++;
  19.       }      
  20. }               //y si algun array entrada aun tiene elementos por añadir...
  21.     while(b<longitud_b){
  22.         if(array_b[b]>array_c[c]){
  23.             array_c[c]=array_b[b];
  24.             c++;
  25.         }
  26.         b++;        
  27.     }
  28.     while(a<longitud_a){
  29.         if(array_a[a]>array_c[c]){
  30.             array_c[c]=array_a[a];    
  31.             c++;
  32.         }
  33.         a++;
  34.     }    
  35. printf("array_c: ");                        
  36. for(a=0; a<=c; a++){                  
  37.     printf("%i ", array_c[a]);              
  38. }
  39. printf("n");
  40. return 0;
  41. }
  42.  

Gracias por tu ayuda; a ver si pillo como se hace...la cosa es que el array_c empieza bien, pero le faltan números por mostrar...
Un saludo!

ermiguel1979

  • Miembro activo
  • **
  • Mensajes: 45
    • Ver Perfil
Re: Vector compuesto de dos vectores...
« Respuesta #8 en: Domingo 10 de Enero de 2010, 12:05 »
0
ProfesorX, gracias por el código. Ya lo he aplicado y funciona OK. Es mas sencillo de implementar, aunque no se me habría ocurrido hacerlo así.
Está muy bien cuando recorres el vector desde la segunda posición comparándola con la anterior y luego, en caso de que sean identicas, igualas el resto del vectro a su posición siguiente...

Vaya máquinas estasi hechos.

Gracias a todos por vuestra atención!!!

Un saludo.