elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++  (Leído 6,028 veces)
DarkSun812

Desconectado Desconectado

Mensajes: 19


Ver Perfil
Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« en: 16 Marzo 2022, 02:20 am »

     Hola, espero que todos tengan un buen día.
Necesito su ayuda para entender la forma más eficiente de trabajar con muchos datos...
Tengo un archivo que tiene como 2.000.000 de datos, divididos en 4 columnas.

     El formato sería algo así:

3554
4562
11     11
12     12
0,00  0,00  0,00
12     13     15     16
11     11     11     11
20     20     20     30

     Como pueden ver, primero encuentro 2 líneas con 1 columna, luego 2 líneas con 2 columnas, luego una línea con 3 columnas y por último comienzan las 2.000.000 líneas con 4 columnas, todos los valores son decimales y estan separados por un espacio. Lo que quiero es saltarme las primeras 5 líneas del archivo y encerrar todos los valores de 4 columnas en una matriz. No sé cuál es la forma más eficiente de hacerlo, ya que hay tantos datos que el código puede llevar mucho tiempo.

     Estaba pensando en encerrar todo en un array, pero no siempre serán 2 000 000 de filas, ocasionalmente serán 2 500 000 o menos y necesito asignar el espacio de memoria que necesitará para ese caso.

     Me dijeron que era más eficiente encerrar cada columna en vectores, pero no tengo idea de cómo usarlos... Soy nuevo en C++ y no soy muy bueno con los punteros y los códigos que encontré en el internet para separar datos usando espacios en blanco no los entiendo. Trabajo con un archivo txt.

     Si alguien me puede explicar mejor esto, se lo agradecería mucho y de ser posible mostrarme un ejemplo de como hacerlo.


En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.355


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #1 en: 16 Marzo 2022, 15:26 pm »

Deberías guardar datos en formato binario, no en formato texto.

Un fichero pequeñito, no tiene importancia guardarlo en texto, pero si el fichero es grande, guardarlo en formato textual conllevará bastante más tiempo tanto leerlo como escribirlo en formato texto, especialmente si hay un formato que deba ser tratado. Si lo guardas en formato binario, la cosa cambia... además no se precisa ningún separador, la separación de cada dato se basa en la cantidad de bytes del tipo de datos usado (se supone que todos esos 2 millones tienene el mismo tipo, si no es así procede usar una estructura, donde se declare cada tipo usado).

También procede dejar esa cabecera en otro fichero aparte, así tienes más libertad para leer y escribir el fichero sin 'molestias'. Otra solución es escribir dicha cabecera al final del fichero, pero sabiendo en todo momento cuantos bytes forman dicha cabecera (si fuera variable). Pero vamos si va a otro fichero aparte, simplificas el tratamiento de cada fichero aunque tengas que tratar con dos.


En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #2 en: 16 Marzo 2022, 16:14 pm »

Creo que el fichero es tal cual y no puede modificar su estilo, como cuando en el trabajo te dicen: esto es lo que debes consumir y quiero que hagas esto.

Saltarse esa cabecera, en C++ no sé, pero en C sería:
Código
  1. fscanf(archivo, "%*d\n"
  2.                "%*d\n"
  3.                "%*d %*d\n"
  4.                "%*d %*d\n"
  5.                "%*d,%*d %*d,%*d %*d,%*d\n");

O si controlas las comas decimales mediante configuración de localización:
Código
  1. fscanf(archivo, "%*d\n"
  2.                "%*d\n"
  3.                "%*d %*d\n"
  4.                "%*d %*d\n"
  5.                "%*f %*f %*f\n");
En línea

DarkSun812

Desconectado Desconectado

Mensajes: 19


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #3 en: 16 Marzo 2022, 22:51 pm »

     Me interesa esa opcion de trabajar con archivos bianrios, pero por desgracia ese formato no se me puede entregar de otra manera, conoce alguna manera de convertirno en formato binario y trabajarlo de la manera que me dices en ese otro archivo convertido??

     Muchas gracias por la respuesta, como dije soy nuevo en este lenguaje y estoy aprendiendo a los golpes, como dicen por ahi me clavo un puñal en la mano jajajaja.

     Hasta ahora encontre una manera de hacerlo con la funcion getline, pero como dices es engorroso hacerlo y me da la impresion de que no es muy eficiente... Al trabajar con millones de datos la eficiencia es algo que debo cuidar desde el incio. Por lo que si conoces una manera de convertir ese archivo a formato binario para posteriormente obtener las columnas y encerrarlas en un vector o un array entonces estaria mas que agradecido.



Creo que el fichero es tal cual y no puede modificar su estilo, como cuando en el trabajo te dicen: esto es lo que debes consumir y quiero que hagas esto.

Saltarse esa cabecera, en C++ no sé, pero en C sería:
Código
  1. fscanf(archivo, "%*d\n"
  2.                "%*d\n"
  3.                "%*d %*d\n"
  4.                "%*d %*d\n"
  5.                "%*d,%*d %*d,%*d %*d,%*d\n");

O si controlas las comas decimales mediante configuración de localización:
Código
  1. fscanf(archivo, "%*d\n"
  2.                "%*d\n"
  3.                "%*d %*d\n"
  4.                "%*d %*d\n"
  5.                "%*f %*f %*f\n");

Holaa, gracias por tu respuesta, aunque ya resolvi como hacerlo con la funcion getline que lee linea por line el documento y solo coloque un contador junto con un if que me ejecutara el codigo cuando el contador informase que estaba en la linea que necesitaba, pero me da curiosidad porque no se como trabajar con el scanf. Cual es la eficiencia del scanf?? Se puede utilizar para hacer lo que te comento de agarrar cada columna y encerrarla en una variable??
« Última modificación: 17 Marzo 2022, 11:08 am por Eternal Idol » En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #4 en: 16 Marzo 2022, 23:13 pm »

Puedes decir que todos las cifras de esa tabla gigante tienen un número fijo de dígitos o es algo arbitrario? Lo digo porque si fueran todos de dos dígitos, como muestras en el ejemplo, con un poco de matemáticas sacas la dimensión de la tabla.
En línea

DarkSun812

Desconectado Desconectado

Mensajes: 19


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #5 en: 17 Marzo 2022, 00:58 am »

Puedes decir que todos las cifras de esa tabla gigante tienen un número fijo de dígitos o es algo arbitrario? Lo digo porque si fueran todos de dos dígitos, como muestras en el ejemplo, con un poco de matemáticas sacas la dimensión de la tabla.

El formato como tal es asi:
Código
  1. 1.21548 4.12354 3.14485 0.0054
  2. -1.21548 4.12354 -3.14485 0.0054
  3. -1.21548 4.12354 3.14485 0.0054
  4. 1.21548 4.12354 3.14485 0.0054
  5. 0 0 0 0.0235
  6. 0 0 0 0.2015
  7. 0 0 0 0.5043
  8.  

El formato de vez en cuando varia, lo normal es que sean 4 columnas tipo flotantes, pudiendo ser negativas o positivas. con 1 numero y 5 decimales las primeras 3 columnas y la 4ta columna de un cero y 4 decimales.

De vez en cuando puede ocurrir que den las primeras 3 columnas 0 o alguna que otra columna de 0.
En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #6 en: 17 Marzo 2022, 17:58 pm »

Pues no, no hay una forma rápida de hacerlo.
Tal vez en vez de querer ponerlo todo en un array o tabla de dos millones de filas que va consumir muchísima memoria, deberías pensar de trabajar con fracciones de 500 o de mi filas. Mucho más manejable y bastante más rápido en cargarlo en memoria.
En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #7 en: 17 Marzo 2022, 23:10 pm »

¿Realmente has probado el programa a ver si funciona lento? Porque si eres nuevo en el lenguaje, optimizar va a complicar las cosas.

Porque hay unas cuantas maneras de acelerarlo. Primero, no leer el archivo línea a línea ni número por número sino en bloques grandes, y luego procesar los bytes desde RAM. Los procesadores modernos tienen instrucciones muy eficientes para ello, a las que se puede acceder mediante funciones especiales (intrinsics), y aunque no son estándar de C++, todos los compiladores modernos las proporcionan. Esto podría hacer el proceso unas 5-10 veces más rápido que usando fscanf o streams. El problema es que es demasiado complicado para alguien que empieza.

Hay algunas cosas más sencillas que podrías probar, siempre que de verdad lo necesites. En Google o en cualquier manual de C puedes encontrar explicaciones de las funciones que voy a mencionar.

Preguntabas sobre la eficiencia de fscanf, y la verdad es que depende. Varia según el tipo de datos a leer y el compilador. Para números de punto flotante, fscanf suele ser bastante más rápido que usar streams (inputFile >> flotante), así que si quieres leer directamente del archivo esa podría ser una opción a probar.

Otra cosa que se suele hacer es, como te dije al principio, leer bloques de bytes grandes de una vez (incluso el archivo completo, dependiendo de su tamaño). En este caso ya no usarías ni fscanf ni el operador >> . Podrías usar sscanf, que funciona como fscanf, pero lee desde un buffer de memoria en lugar de un archivo. El detalle es que, como estamos hablando de bloques grandes de bytes, para que sscanf funcione eficientemente, antes habría que modificar el buffer (en tu caso, básicamente sustituir los '\n' por '\0'). Aún así, seguro que sería más eficiente que las opciones anteriores. Otra forma sería usar strtok, para irte saltando los espacios y comas, y la función stof (o atof, que es más rápida, pero no detecta errores) para convertir el texto en floats. Creo que esto podría ser unas 2 o 3 veces más rápido que las soluciones obvias (fscanf/operador >>). Eso sí, si no lees el archivo completo de golpe, es posible que a veces los bloques leídos terminen a la mitad de una cantidad. No es difícil detectar esto, pero hay que tenerlo en cuenta.

Todo esto es de C, porque C++ ofrece alternativas (std::regex, std:: string y sus funciones como find_first_of, find_first_not_of, etc.) que muchas veces son más completas o seguras, pero precisamente por eso, suelen ser más lentas si lo que quieres hacer es algo simple, como en este caso.

Lo dicho, cualquiera de estas opciones hace el problema más complejo, aunque me parece que estas últimas que te puse son asequibles con leer un poco. Pero como escribí al inicio, primero deberías comprobar que de verdad necesites optimizar.
En línea

DarkSun812

Desconectado Desconectado

Mensajes: 19


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #8 en: 18 Marzo 2022, 00:55 am »

     Gracias por tu respuesta, tendre en cuenrta todo lo que me comentas si llega la hora de optimizar.

Lo dicho, cualquiera de estas opciones hace el problema más complejo, aunque me parece que estas últimas que te puse son asequibles con leer un poco. Pero como escribí al inicio, primero deberías comprobar que de verdad necesites optimizar.

     Por ahora voy a dejar de lado la optimizacion y me enfocare en que el programa funcione y haga lo que le pido, ya me dieron un regaño por no entregar resultados asi que me preocupare de hacerlo de la manera mas eficiente cuando se me solicite explicitamente. Por el momento me pidieron graficar los datos en un grafico de dispersion de puntos, algo similar al scatter de matplotlib de python. Tienes alguna idea de que librerias puedo usar para hacerlo? Porque de verdad estoy retrasado en el trabajo y llevo todo el dia investigando sobre el tema sin conseguir resultados. Gracias nuevamente por las recomendaciones que me diste, sobre el tema de las librerias graficas, en el foro coloque otro tema por si quieres responder por ahi.
En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Tengo una duda sobre los punteros, trabajar con archivos, arrays y vectores. En c+++
« Respuesta #9 en: 23 Marzo 2022, 20:31 pm »

     Gracias por tu respuesta, tendre en cuenrta todo lo que me comentas si llega la hora de optimizar.

     Por ahora voy a dejar de lado la optimizacion y me enfocare en que el programa funcione y haga lo que le pido, ya me dieron un regaño por no entregar resultados asi que me preocupare de hacerlo de la manera mas eficiente cuando se me solicite explicitamente. Por el momento me pidieron graficar los datos en un grafico de dispersion de puntos, algo similar al scatter de matplotlib de python. Tienes alguna idea de que librerias puedo usar para hacerlo? Porque de verdad estoy retrasado en el trabajo y llevo todo el dia investigando sobre el tema sin conseguir resultados. Gracias nuevamente por las recomendaciones que me diste, sobre el tema de las librerias graficas, en el foro coloque otro tema por si quieres responder por ahi.

No había visto tu respuesta. Supongo que ya lo solucionaste (¿?) pero veo que en otro tema decías que estabas teniendo problemas de rendimiento. Si aún no los has solucionado, me parece (al menos con los detalles que proporcionaste allá), que tu problema pide a gritos paralelización, por ejemplo, mediante hilos. No especificaste qué haces con los flotantes que lees, pero si no solamente te limitas a leerlos y pasarlos a la función que grafica, sino que además realizas operaciones sobre ellos, esto podría mejorar el rendimiento de forma importante.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Duda en búsqueda en vectores de punteros en C
Programación C/C++
megamole 4 3,078 Último mensaje 26 Julio 2010, 18:50 pm
por megamole
Duda/Error sobre arrays (vectores)
Programación C/C++
Ikuza 1 1,707 Último mensaje 2 Diciembre 2015, 15:03 pm
por class_OpenGL
Tengo una duda con los punteros
Programación C/C++
astroman20 1 1,566 Último mensaje 10 Agosto 2017, 11:47 am
por ivancea96
Tengo algunas dudas sobre punteros en C/C++ y otras cosillas.
Programación C/C++
Gojira 5 3,139 Último mensaje 25 Febrero 2018, 02:33 am
por MAFUS
tengo una una pequeña duda, sobre vectores
Programación C/C++
Emily 4 3,562 Último mensaje 19 Enero 2022, 22:12 pm
por K-YreX
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines