Autor
|
Tema: Ayuda ordenar y eliminar palabras texto (Leído 7,871 veces)
|
Fire_Hugo12
Desconectado
Mensajes: 4
|
Hola soy nuevo en el foro y quisiera ver si me pueden ayudar con este programa... lo que hace es dado un texto ingresado muestra la cantidad de ocurrencias que tiene cada palabra, pero las muestra desordenadas, por ejemplo "hola amigo que que" ... la salida seria: hola->1 amigo->1 que->2 como puedo hacer para que me los muestre ordenados de mayor a menor en numero de ocurrencias? y otra duda.. como puedo hacer para eliminar la mas baja o las mas bajas? Gracias de antemano, aqui esta mi codigo: /* Recibe una cadena y devuelve las palabras de dicha cadena. Los espacios y saltos de linea son los separadores entre palabras. */ void separador(char renglon[80], char palabras[100][80], int *total) { int i, j=0;
for(i=0; i<strlen(renglon); i++) { /* Si es un caracter distinto de espacio y salto de linea */ if(renglon[i]!=' ' && renglon[i]!='\n') { palabras[*total][j] = renglon[i]; j++;
/* Si el caracter siguiente es fin de cadena */ if(renglon[i+1]=='\0') { palabras[*total][j] = '\0'; /* Indica fin de palabra */ *total = *total+1; /* Aumenta el numero de palabras */ j=0; } } /* Si es espacio o salto de linea */ else if(renglon[i]==' ' || renglon[i]=='\n') { /* Si el caracter anterior no es espacio ni salto de linea */ if(i>0 && renglon[i-1]!=' ' && renglon[i-1]!='\n') { palabras[*total][j] = '\0'; /* Indica fin de palabra */ *total = *total+1; /* Aumenta el numero de palabras */ j=0; } } } }
void ocurrencias(char nombre_archivo[100]) { char renglon[80]; char palabras[100][80]; /* Todas las palabras */ char palabras_diferentes[100][80]; /* Solo palabras diferentes */ int i, j, k, total=0 /* Numero total de palabras*/, diferentes=0 /* Numero de palabras diferentes */; int Rep[100]; /* Repeticiones de cada palabra diferente */
FILE *archivo;
archivo=fopen(nombre_archivo,"r");
if(archivo==NULL) { printf("No se encuentra archivo: %s\n", nombre_archivo); return ; }
/* Lee el archivo linea a linea y obtiene las palabras de esa linea */ while(fgets(renglon,80,archivo)) { separador(renglon,palabras, &total); }
fclose(archivo);
/* Saca copia del arreglo original */ for(i=0; i<total; i++) strcpy(palabras_diferentes[i], palabras[i]);
/* Saca palabras diferentes */ diferentes = total; for(i=0;i<diferentes;i++) { for(j=i+1;j<diferentes;j++) { /* Si encuentra palabra repetida */ if(!strcmp(palabras_diferentes[i], palabras_diferentes[j])) { /* Recorre una posicion elementos posteriores */ for(k=j+1;k<diferentes;k++) strcpy(palabras_diferentes[k-1], palabras_diferentes[k]);
diferentes--; j--; } } }
/* haya repeticiones de cada palabra distinta */ for(i=0; i<diferentes; i++) Rep[i] = 0; for(i=0; i<diferentes; i++) for(j=0;j<total;j++) if(!strcmp(palabras_diferentes[i], palabras[j])) Rep[i]++;
/* Muestra informacion */ printf("Palabras y numero de ocurrencias del archivo: %s\n\n", nombre_archivo); printf("Total de palabras: %d\n", total); printf("Palabras distintas: %d\n\n", diferentes);
for(i=0; i<diferentes; i++) printf("%s -> %d\n", palabras_diferentes[i], Rep[i]); }
|
|
|
En línea
|
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
Tu podrías estar buscando esto: Ordenamiento burbuja en C++ordena una lista de enteros podrias hacer un array con las veces que se repiten las palabras, o mejor aún hacer una estructura de este tipo: typedef struct WordInfo { PCHAR lpWord; ULONG nRep; } lpWord, puntero a la palabra. nRep, las veces que se repite la palabra. de esta forma lo tienes mejor ordenado.
|
|
|
En línea
|
|
|
|
naderST
|
Tu podrías estar buscando esto: Ordenamiento burbuja en C++ordena una lista de enteros podrias hacer un array con las veces que se repiten las palabras, o mejor aún hacer una estructura de este tipo: typedef struct WordInfo { PCHAR lpWord; ULONG nRep; } lpWord, puntero a la palabra. nRep, las veces que se repite la palabra. de esta forma lo tienes mejor ordenado. Sin ánimos de ofender amigo, considero que lo más correcto es que el código que coloques para este tipo de casos sea código estándar, ya que no sabemos que compilador está utilizando Fire_Hugo12. Por las dudas tenemos que PCHAR es equivalente a un apuntador a caracter (char *) y ULONG es equivalente a un entero largo sin signo (unsigned long int). Con respecto al problema puedes utilizar una lista enlazada e ir insertando de manera ordenada en tu caso de mayor a menor. Para eliminar la más baja o las más bajas vas recorriendo palabra a palabra y comprobando si no es la más baja la concatenas en otra nueva cadena y reduces el contador de dicha palabra, esto lo haces hasta que dicho contador llegue a cero.
|
|
« Última modificación: 16 Diciembre 2012, 07:32 am por naderST »
|
En línea
|
|
|
|
x64core
Desconectado
Mensajes: 1.908
|
Sin ánimos de ofender amigo, considero que lo más correcto es que el código que coloques para este tipo de casos sea código estándar, ya que no sabemos que compilador está utilizando Fire_Hugo12. Por las dudas tenemos que PCHAR es equivalente a un apuntador a caracter (char *) y ULONG es equivalente a un entero largo sin signo (unsigned long int). Con respecto al problema puedes utilizar una lista enlazada e ir insertando de manera ordenada en tu caso de mayor a menor. Para eliminar la más baja o las más bajas vas recorriendo palabra a palabra y comprobando si no es la más baja la concatenas en otra nueva cadena y reduces el contador de dicha palabra, esto lo haces hasta que dicho contador llegue a cero.
Claro todo el mundo sabe eso, ni siquiera tengo la idea de porque lo mencionas. respecto al tema se tendría que mirar tu código y de que forma lo implementas para saber si es tan veloz y eficiente.
|
|
|
En línea
|
|
|
|
Fire_Hugo12
Desconectado
Mensajes: 4
|
Gracias a las 2 por las respuestas, ya logre ordenarlo por cantidad de repeticiones... lo unico que me falta y tengo una duda es en la parte de borrar los menores, tengo que "v" es el menor numero de repeticiones pero me da un error en la funcion, me dice "error: too few arguments to function 'void borrar(tipoNodo**, int) " que puede ser? (el compilador que uso es el codeblock) void borrar(Lista *lista, int v) { pNodo anterior, nodo;
nodo = *lista; anterior = NULL; while(nodo && nodo->valor < v) { anterior = nodo; nodo = nodo->siguiente; } if(!nodo || nodo->valor != v) ; else { /* Borrar el nodo */ if(!anterior) /* Primer elemento */ *lista = nodo->siguiente; else /* un elemento cualquiera */ anterior->siguiente = nodo->siguiente; free(nodo); } }
|
|
|
En línea
|
|
|
|
naderST
|
Gracias a las 2 por las respuestas, ya logre ordenarlo por cantidad de repeticiones... lo unico que me falta y tengo una duda es en la parte de borrar los menores, tengo que "v" es el menor numero de repeticiones pero me da un error en la funcion, me dice "error: too few arguments to function 'void borrar(tipoNodo**, int) " que puede ser? (el compilador que uso es el codeblock) void borrar(Lista *lista, int v) { pNodo anterior, nodo;
nodo = *lista; anterior = NULL; while(nodo && nodo->valor < v) { anterior = nodo; nodo = nodo->siguiente; } if(!nodo || nodo->valor != v) ; else { /* Borrar el nodo */ if(!anterior) /* Primer elemento */ *lista = nodo->siguiente; else /* un elemento cualquiera */ anterior->siguiente = nodo->siguiente; free(nodo); } } Ojo CodeBlocks es el IDE lo más seguro es que tu compilador sea GCC. Podrías colocar el fragmento de código donde haces el llamado a la función borrar? Claro todo el mundo sabe eso, ni siquiera tengo la idea de porque lo mencionas. respecto al tema se tendría que mirar tu código y de que forma lo implementas para saber si es tan veloz y eficiente.
No todo el mundo lo sabe, por eso lo menciono y como he visto varios posts que respondes y colocas código NO estándar quise hacer la acotación, pero OJO esto no es nada personal, simplemente te lo digo porque a MI parecer es lo más correcto, no quiero caer en discusiones acerca del tema. No tengo ninguna implementación, pero en esencia es lo mejor ir insertando de manera ordenada en una lista enlazada o un arreglo para que al momento de eliminar la palabra o las palabras con el número menor de ocurrencias se sabe de ante mano que es la última en la lista o en el arreglo.
|
|
|
En línea
|
|
|
|
Fire_Hugo12
Desconectado
Mensajes: 4
|
la llamo dentro de un switch en el main: //dependiendo la opc del menu switch(opc) { case 1: ingresar(); system("cls"); break; case 2: busqueda(); getch(); break; case 3: cout<<"El Numero de Repeticion que desea eliminar es: "; cin>> v; borrar(); break; } }while(opc!=4); }
|
|
« Última modificación: 16 Diciembre 2012, 23:34 pm por Fire_Hugo12 »
|
En línea
|
|
|
|
naderST
|
la llamo dentro de un switch en el main: //dependiendo la opc del menu switch(opc) { case 1: ingresar(); system("cls"); break; case 2: busqueda(); getch(); break; case 3: cout<<"El Numero de Repeticion que desea eliminar es: "; cin>> v; borrar(); break; } }while(opc!=4); } La función borrar recibe dos parámetros y no le estás pasando ninguno, debes pasarle la lista y el valor.
|
|
|
En línea
|
|
|
|
Fire_Hugo12
Desconectado
Mensajes: 4
|
aaah oks gracias naderST y x64Core ya solucione el problema y termine el programa
|
|
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Algo que preocupa, en base a los fragmentos de código fuente, es no utilizar la biblioteca estándar de C++. Por ejemplo puedes leer la linea con getline, obtener las palabras de ella con un objeto de tipo stringstream, evitar los duplicados con un mapa, etc. Un ejemplo de ello (sin validaciones) es: #include <iostream> #include <string> #include <sstream> #include <map> #include <vector> #include <algorithm> using namespace::std; typedef vector<map<string, int>::iterator>::size_type vec_iter_sz; bool cmp(map<string, int>::iterator a, map<string, int>::iterator b); int main() { cout << "Introduce la linea: "; string linea; getline(cin, linea); stringstream in(linea); string palabra; map<string, int> frec; vector<map<string, int>::iterator> ndx; while (in >> palabra) { map<string, int>::iterator it = frec.find(palabra); if (it == frec.end()) { frec[palabra] = 1; ndx.push_back(frec.find(palabra) ); } else frec[palabra]++; } sort(ndx.begin(), ndx.end(), cmp); for (vec_iter_sz i = 0; i != ndx.size(); i++) cout << ndx[i]->first << " (" << ndx[i]->second << ")" << endl; return 0; } bool cmp(map<string, int>::iterator a, map<string, int>::iterator b) { return a->second < b->second || a->second == b->second && a->first <= b->first; }
Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Este teléfono transcribe en texto las palabras de tu interlocutor
Noticias
|
wolfbcn
|
0
|
1,392
|
13 Junio 2013, 01:17 am
por wolfbcn
|
|
|
Como ordenar alfabéticamente palabras en C++
Programación C/C++
|
loko5755
|
4
|
22,462
|
5 Mayo 2014, 12:04 pm
por eferion
|
|
|
Obtener y ordenar texto CMD y MediaInfo Cli
Scripting
|
betitogc2
|
3
|
3,719
|
31 Marzo 2015, 19:36 pm
por betitogc2
|
|
|
(BATCH) Eliminar lineas que NO contengan ciertas palabras..
Scripting
|
Afkael
|
7
|
7,586
|
30 Noviembre 2015, 07:05 am
por explorer
|
|
|
Eliminar palabras
Programación C/C++
|
Sothu
|
3
|
2,489
|
1 Diciembre 2015, 01:43 am
por daryo
|
|