Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DGP en 8 Marzo 2021, 20:01 pm



Título: Problema fusionando pilas
Publicado por: DGP en 8 Marzo 2021, 20:01 pm
Aca esta el codigo pero no logro fusionar las pilas quien me ayudaria a ver cual es mi error aqui


Código
  1. /*Se tiene dos pilas (stacks) que contienen números enteros, elabore un programa que fusione
  2. ambas pilas en una Tercera y muestre el promedio de la tercera  pila. Ademas cargue una  cola  
  3. donde determine el promedio de los datos de ésta Utilice un menú donde especifique  
  4. cada acción (cargar, mostrar, fusión y promedio) */
  5.  
  6. #include<iostream>
  7. #include<stdlib.h>
  8.  
  9. using namespace std;
  10.  
  11. struct Nodo{
  12. int dato;
  13. Nodo *sig;
  14. };
  15.  
  16. void Pilas_1(Nodo *&, int);
  17. void Pilas_2(Nodo *&, int);
  18. void MostrarPila_1(Nodo *&);
  19. void MostrarPila_2(Nodo *&);
  20. void FusionarPilas(Nodo *&, Nodo*&);
  21.  
  22. int main(){
  23.  
  24. Nodo *pila = NULL;
  25. Nodo *p1 = NULL;
  26. Nodo *p2 = NULL;
  27.  
  28. int opc = 0, n, i=0, datos;
  29.  
  30. do{
  31. cout<<"\tMenu"<<endl;
  32.    cout<<"1. Agregar datos"<<endl;
  33. cout<<"2. Mostrar datos"<<endl;
  34. cout<<"3. Fusionar datos "<<endl;
  35. cout<<"4. Promedio de los datos"<<endl;
  36. cout<<"5. Salir"<<endl;
  37. cout<<"\n Escriba un numero de la lista: ";
  38. cin>>opc;
  39.  
  40. switch(opc){
  41.  
  42. case 1: cout<<"\nPilas a agregar: "; cin>>n;
  43. cout<<"\nDatos de la pila 1"<<endl;
  44. for(i=0;i<n;i++){
  45.    cout<<"\nAgregue un numero: "; cin>>datos;
  46.    Pilas_1(p1,datos);
  47.    }
  48.  
  49.    cout<<"\nDatos de la pila 2"<<endl;
  50. for(i=0;i<n;i++){
  51.    cout<<"\nAgregue un numero: "; cin>>datos;
  52.    Pilas_1(p2,datos);
  53.    }
  54.  
  55.    system("pause");
  56. break;
  57.  
  58.  
  59. case 2: cout<<"\nLos datos agregados en la pila 1 son: "<<endl;
  60.        MostrarPila_1(p1);
  61. cout<<"\nLos datos agregados en la pila 2 son: "<<endl;
  62.        MostrarPila_2(p2);
  63. system("pause");
  64.     break;
  65.  
  66. case 3: cout<<"\nLa pila 1 con la pila 2"<<endl;
  67.       FusionarPilas(p1,p2);
  68.       system("pause");
  69.     break;
  70.  
  71. }
  72.   system("cls");
  73. }
  74. while(opc != 5);
  75.  
  76. return 0;
  77. }
  78.  
  79. void Pilas_1(Nodo *&pila, int n){
  80.  
  81. Nodo *nuevo_nodo = new Nodo();
  82. nuevo_nodo->dato = n;
  83. nuevo_nodo->sig = pila;
  84. pila = nuevo_nodo;
  85.  
  86. cout<<"\nDatos agregados correctamente"<<endl;
  87.  
  88. }
  89.  
  90.  
  91. void MostrarPila_1(Nodo *&p1){
  92.  
  93. while(p1 != NULL){
  94.            cout<<p1->dato<<endl;
  95.            p1 = p1->sig;
  96.     }    
  97. }
  98.  
  99. void MostrarPila_2(Nodo *&p2){
  100.  
  101. while(p2 !=NULL){
  102.            cout<<p2->dato<<endl;
  103.            p2 = p2->sig;
  104.     }    
  105. }
  106.  
  107. void FusionarPilas(Nodo *&p1, Nodo *&p2){
  108.  
  109.    Nodo *aux = new Nodo();
  110.  
  111. aux = p1;
  112.  
  113.        while(aux != NULL){
  114.        aux = aux->sig;
  115.        aux->sig = pila;
  116.    }
  117. }

MOD: Titulo modificado a algo descriptivo


Título: Re: Problema fusionando pilas
Publicado por: AlbertoBSD en 8 Marzo 2021, 20:05 pm
Me detuve después de ver la estructurara de Datos, lo que muestras es a estructura de Una Lista ligada no de una Pila, desde ahí esta mal el código.

Por cierto seria mejor colocar un Titulo mas explicito como "Problema fusionando Pilas"

MOD: Titulo corregido.


Título: Re: Problema fusionando pilas
Publicado por: K-YreX en 9 Marzo 2021, 06:57 am
Bueno pues a ver... Varias cosas a mencionar:
  • Pongo esto lo primero porque creo que es el error más básico de todos: El código me hace sospechar que tienes un problema con el ámbito de las variables. La pila que creas en la línea 24, la utilizas únicamente en la 115 además de forma muy extraña.
Cuando en una función estableces el nombre de una variable, puede ser cualquiera. Este nombre solo sirve dentro de la función y realmente se corresponde con el argumento que hayas pasado al llamar a la función. Ver la función mostrarPila() más adelante...
  • La función Pilas_1() no es muy descriptiva. Sería mejor algo como push(p1, dato) simulando las funciones típicas de una pila (push, top, pop)
  • No tiene sentido hacer una función para mostrar una pila y otra para mostrar otra pila. La gracia es tener una única función y mediante parámetros decirle qué pila mostrar en cada momento.
  • Además si mueves el puntero, pierdes la referencia al inicio de la pila. Tienes que crear un puntero auxiliar.
Código
  1. void mostrarPila(Nodo *&p) {
  2.  Nodo *aux = p;
  3.  while(aux != NULL) { // En C++ para punteros no se debe usar NULL sino nullptr
  4.    cout << aux->dato << " ";
  5.    aux = aux->sig;
  6.  }
  7. }
  8. // Para mostrar las pilas 1 y 2:
  9. mostrarPila(p1); // Aqui la variable p que se usa en la funcion hace referencia a p1
  10. mostrarPila(p2); // Ahora la misma variable p hace referencia a p2

Yendo al grano ahora, la función para fusionar pilas deberías ser algo así:
Código
  1. void fusionarPilas(Nodo *&p1, Nodo *&p2, Nodo *&fusion) {
  2.  // Recorres p1 como si fueras a mostrarla pero en vez de mostrarla vas guardando cada elemento en fusion...
  3.  // Tu codigo aqui
  4.  // Recorres p2 como si fueras a mostrarla pero en vez de mostrarla vas guardando cada elemento en fusion...
  5.  // Tu codigo aqui
  6. }
  7. // Para llamar a la funcion:
  8. fusionarPilas(p1, p2, pila); // La fusion se guardara en la pila <pila> de la linea 24
  9.  
Es mejor hacerlo así para no modificar las pilas originales y guardar la fusion en otra diferente.
Si completas este código correctamente, debería funcionar y para comprobarlo ya sabes:
Código
  1. mostrarPila(pila);

Además fíjate que en tu función creas un nodo nuevo (línea 109) y luego apuntas a p1. Ese nodo nuevo se pierde, no sirve para nada.
PD: Estás trabajando con memoria dinámica (al utilizar new). Por tanto, antes de acabar el programa, debes eliminar toda esa memoria reservada mediante delete (nodo a nodo).

PD2: No es recomendable utilizar system("pause"). La mejor alternativa en C++ es utilizar cin.get() para el mismo propósito.

PD3: Las bibliotecas en C++ no llevan .h y en cambio llevan una c al principio: stdlib.h (versión C) -> cstdlib (versión C++) Funciona de todas formas por la compatibilidad con C pero no es lo más correcto.