Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Generar un numero variable de nodos para una lista

Estas en el tema de Generar un numero variable de nodos para una lista en el foro de C/C++ en Foros del Web. Buenas noches, disculpen la molestia. Me encuentro realizando un algoritmo que lee una serie de datos de un archivo, los almacena en objetos de una ...
  #1 (permalink)  
Antiguo 29/09/2014, 20:33
 
Fecha de Ingreso: abril-2012
Mensajes: 12
Antigüedad: 12 años
Puntos: 0
Busqueda Generar un numero variable de nodos para una lista

Buenas noches, disculpen la molestia. Me encuentro realizando un algoritmo que lee una serie de datos de un archivo, los almacena en objetos de una clase que he creado, y luego esos objetos van a una lista.

Ahora, el problema que tengo es que el numero de objetos que debo crear es algo que viene dado en archivo que leo. No se como crear la cantidad de nodos necesaria, ya que no siempre la cantidad de objetos para agregar en la lista sera igual.

He pensado que quiza podria agregar a mi algoritmo la habilidad de agregar nodos mediante el nombre de una variable. Por ejemplo, si tengo una cadena de caracteres llamada "nombre" y que contenga "nodo1" como valor inicial, y fuera cambiando el nombre de la variable cada vez que necesite crear un nodo (nodo1, nodo2, nodo3...). Pero no se si pueda hacerse algo como esto...

Código C++:
Ver original
  1. string nombre = "nodo1"; //Ir cambiando este valir a medida que avanza el algoritmo
  2. nodo nombre; //El valor de nodo tendria que ser nodo1, que es lo que contiene la variable nombre

Les muestro parte de mi codigo, sinceramente no se trabajar bien con listas y a esto es a lo que he podido llegar hasta ahora. Si existe una forma de enlazar cada nodo a su siguiente sin hacer lo que se me ocurrio en principio, estaria inmensamente agradecido con su ayuda. El archivo Datos.txt contiene un numero en su primera linea, que indica el numero de objetos que tendre, y luego la lista de objetos, uno por linea.

Código C++:
Ver original
  1. using namespace std;
  2. class cosa {
  3.     public:
  4.         string nombre;
  5.  
  6.         cosa(){ //Constructor
  7.         nombre = "default";
  8.             }
  9. };
  10.  
  11. struct Nodo{ //Nodo
  12.     cosa G1;
  13.     struct Nodo *sig, *ant;
  14. };
  15. struct Nodo *inicio, *final;
  16.  
  17. int main(){
  18.         int cantidad=0;
  19.     int comodin3;
  20.     int operaciones;
  21.     string comodin1;
  22.     char comodin2[1000];
  23.    
  24.     struct Nodo *sujetos;
  25.     sujetos=new(struct Nodo);
  26.    
  27.     ifstream archivo;
  28.     archivo.open("datos.txt");
  29.             if (archivo == NULL){
  30.                 cout << "El archivo no existe \n" << endl;
  31.                 exit (EXIT_FAILURE);
  32.             }else{ 
  33.    
  34.         archivo.getline(comodin2, 1000, '\n'); //Lectura de numero de objetos
  35.         cantidad = atoi(comodin2);
  36.  
  37.             for (int i=0; i<cantidad; i++){
  38.            
  39.             archivo.getline(comodin2, 1000, '\n'); //Lectura de nombre
  40.             sujetos->G1.nombre = comodin2;
  41.            
  42. //
  43. //  Por aca tendria que agregar el objeto al nodo y enlazar al siguiente
  44. //  Por aca tendria que agregar el objeto al nodo y enlazar al siguiente
  45. //  Por aca tendria que agregar el objeto al nodo y enlazar al siguiente
  46. //  Por aca tendria que agregar el objeto al nodo y enlazar al siguiente
  47. //  Por aca tendria que agregar el objeto al nodo y enlazar al siguiente
  48. //
  49.            
  50.         }
  51.     archivo.close();
  52.     }
  53. }

Podrian darme una solucion que me permita agregar ese objeto al nodo y agregar a un siguiente nodo? Ya sea creando uno nuevo o no.

PD: El codigo original es mucho mas largo, he editado todo lo que he podido para hacerlo lo mas legible y sencillo posible, asi que es posible que encuentren por alli alguna variable no declarada o alguna funcion que no existe. Disculpen por el post tan largo.

Última edición por tyrax; 29/09/2014 a las 20:37 Razón: Agregada post data
  #2 (permalink)  
Antiguo 30/09/2014, 05:11
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Generar un numero variable de nodos para una lista

Puede que no me quede clara tu duda, pero me parece que lo que buscas es ir añadiendo los nuevos nodos como siguiente del anterior. Algo asi:

- creas un nodo inicial
- creas un segundo nodo y lo añades como siguiente del primero
- creas un tercer nodo y lo añades como siguiente del segundo
- etc

Es lo que sería una lista simple; en tu codigo tienes una lista doble, es decir, que cada nodo apunta a su anterior y a su siguiente; si el anterior el primero apunta al ultimo y el siguiente del ultimo apunta al primero entonces tienes una lista circular. No se si ya te suena de algo todo esto.

Te propongo un ejemplo de lista simple para ver como añadir nodos al final:

Código C++:
Ver original
  1. class COSA {
  2. public:
  3.     void set_name(string name) {
  4.         this->name = name;
  5.     }
  6.     string get_name() {
  7.         return this->name;
  8.     }
  9.  
  10. private:
  11.     string name;
  12. };
  13.  
  14.  
  15. typedef struct tagNodo{
  16.     class COSA *cosa;
  17.     struct tagNodo *sig;
  18. } Nodo;
  19.  
  20.  
  21. class COSA *crea_cosa(string nombre) {
  22.     class COSA *cosa = 0;
  23.  
  24.     if((cosa = new(nothrow) class COSA)) {
  25.         cosa->set_name(nombre);
  26.     }
  27.  
  28.     return cosa;
  29. }
  30.  
  31.  
  32. void add_cosa(Nodo **lista, class COSA *cosa) {
  33.     Nodo *nuevo_nodo, *ptr;
  34.  
  35.     if((nuevo_nodo = new(nothrow) Nodo)) {
  36.         nuevo_nodo->cosa = cosa;
  37.         nuevo_nodo->sig = 0;
  38.  
  39.         if(!(ptr = *lista)) {
  40.             *lista = nuevo_nodo;
  41.         }
  42.         else {
  43.             while(ptr->sig) {
  44.                 ptr = ptr->sig;
  45.             }
  46.             ptr->sig = nuevo_nodo;
  47.         }
  48.     }
  49. }
  50.  
  51.  
  52. void muestra_cosas(Nodo *lista) {
  53.     Nodo *ptr;
  54.  
  55.     ptr = lista;
  56.     while(ptr) {
  57.         cout << ptr->cosa->get_name() << endl;
  58.         ptr = ptr->sig;
  59.     }
  60. }
  61.  
  62.  
  63. void libera_cosas(Nodo **lista) {
  64.     Nodo *ptr, *sig;
  65.  
  66.     ptr = *lista;
  67.     while(ptr) {
  68.         sig = ptr->sig;
  69.         delete ptr->cosa;
  70.         delete ptr;
  71.  
  72.         ptr = sig;
  73.     }
  74.     *lista = 0;
  75. }
  76.  
  77.  
  78. int main() {
  79.     Nodo *lista_de_cosas;
  80.     COSA *ptr;
  81.  
  82.     lista_de_cosas = 0;
  83.  
  84.     ptr = crea_cosa("una");
  85.     add_cosa(&lista_de_cosas, ptr);
  86.     ptr = crea_cosa("prueba");
  87.     add_cosa(&lista_de_cosas, ptr);
  88.     ptr = crea_cosa("de");
  89.     add_cosa(&lista_de_cosas, ptr);
  90.     ptr = crea_cosa("texto");
  91.     add_cosa(&lista_de_cosas, ptr);
  92.  
  93.     muestra_cosas(lista_de_cosas);
  94.     libera_cosas(&lista_de_cosas);
  95.  
  96.     return 0;
  97. }

Tal como ves puedo seguir añadiendo hasta que se agote la memoria. Hay algunas cosas importantes a tener en cuenta: hacer las comprovaciones de error para el caso de que no haya memoria disponible. En el ejemplo estoy usando new(nothrow) para que no me arroje excepciones y validar directamente el retorno contra nulo (nulo si no hay memoria disponible). Otra cosa importante es iniciar los elementos nulos como nulos (no recuerdo si c++ no hace por defecto, pero es mejor asegurarse), es el caso de la lista_de_cosas, quiero que inicialmente sea nula para que la funcion de añadir entienda que a la primera llamada le envio una lista nula; lo mismo para los punteros 'sig' que hay en la estructura, que antes de ser rellenados con un nodo siguiente quiero que sean nulos. Una ultima cosa, para cada new necesitas un delete, es lo que hago en la funcion de liberar_cosas; en los pc actuales esto de liberar la memoria dinamica solo tiene sentido cuando quieres reutilizar en la misma ejecucion la misma variable para mas de una lista, pero es una buena practica liberar la memoria reservada y por eso te lo pongo.

Otra cosa, ya que estas en c++ porque no usas un contenedor tipo vector o list para hacer estas listas? Te resultará mas fácil y seguramente tendras menos fallos. COn eso te ahorras el trabajo con structs, que en tu ejemplo parece ser que solo las usas para soportar los punteros siguiente y anterior. Tambien puedes separar el manejador de listas en una nueva clase: una clase que se encargará de manejar la lista.

Saludos
vosk
  #3 (permalink)  
Antiguo 30/09/2014, 07:33
 
Fecha de Ingreso: abril-2012
Mensajes: 12
Antigüedad: 12 años
Puntos: 0
Respuesta: Generar un numero variable de nodos para una lista

vosk, muchas gracias por tu respuesta! Creo que esto es justo lo que necesitaba. Ir creando nodos enlazados al anterior sin tener que crearlos manualmente.

En este momento no puedo intentar implementar tu codigo, ya que voy saliendo a la universidad, pero en unas horas cuando llegue a casa lo intentare!

Estare haciendote saber como va mi algoritmo
  #4 (permalink)  
Antiguo 30/09/2014, 13:39
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: Generar un numero variable de nodos para una lista

Ok, una ultima cosa, omití algunas cosas pero tendrias que implementarlas para hacer una aplicacion correcta; p.ej. la funcion que añade el nodo podría ser boleana, de forma que si no puede reservar memoria para la nueva struct retorna 1 (o 0 da igual), en cuyo caso tendrias que liberar la clase COSA creada previamente con 'crea_cosa'. Todas las comprovaciones de error tienen que estar resueltas para cada condicion: sin error sigue la aplicacion, con error libera los recursos, reporta el error y cierra o reinicia el ciclo.

Revisa lo que te comente de los vectores, creo que te será mas facil de implementar.

Saludos
vosk
  #5 (permalink)  
Antiguo 02/10/2014, 01:28
 
Fecha de Ingreso: abril-2012
Mensajes: 12
Antigüedad: 12 años
Puntos: 0
Respuesta: Generar un numero variable de nodos para una lista

Bueno vosk, ya el algoritmo esta terminado. Funciona a la perfeccion, y aunque encontre algunas cosas mas que no sabia como hacer en el camino, esta listo. Muchas gracias por tu ayuda en verdad.

Etiquetas: c++, listas, nodos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:58.