Imprima un histogtwig basado en la longitud de las palabras (C)

Este es un ejercicio de K&R (1-13) …

“Escriba un progtwig para imprimir un histogtwig de la longitud de las palabras en su entrada. Es fácil dibujar el histogtwig con barras horizontales; una orientación vertical es más desafiante”.

La sección trataba sobre matrices y, para ser honesto, no estoy seguro de haberlo entendido bien. Todo hasta este punto era bastante fácil de entender, esto no lo era.

De todos modos estoy intentando hacer un histogtwig con barras horizontales primero. Una vez que logré eso, lo intentaré verticalmente, pero en este momento ni siquiera estoy seguro de por dónde empezar con la versión fácil. (Dormí en él, me desperté y aún no pude conseguirlo).

Dibujé un ejemplo de lo que el progtwig produciría:

---------------------------------------------------------------- 001|XX 002|XXXX 003|X 004|XXXXXXXXXX 005|XXXXXXXXXXXXXXXXXXXXXXXXX 006|XXXX 007|X 008| 009|XXXXXXXXX 010|XXX >10|XXXX ---------------------------------------------------------------- 

Y trató de descomponerlo (el progtwig) en secciones. Esto es lo que se me ocurrió:

  1. IMPRIMIR FRONTERA
  2. IMPRIMA LA CATEGORÍA, IMPRIMA X CADA CONDICIÓN DE TIEMPO ES VERDADERA, IMPRIMA NEWLINE, REPITA.
  3. IMPRIMIR FRONTERA INFERIOR

Pero cuanto más lo pienso, menos creo que es cómo funcionaría (porque getchar() pasa por un personaje a la vez, y no podría volver para poner una X en la categoría correcta). O…

… Estoy realmente confundido en cuanto a cómo resolvería este problema. Aquí está hasta donde he podido obtener código sabio:

 #include  #define MAXWORDLENGTH 10 // print a histogram of the length of words in input. horizontal bar version int main(void) { int c; while ((c = getchar()) != EOF) { } return 0; } 

¿Podría alguien ayudarme a iluminarme? No necesariamente con el código, tal vez solo con un pseudo código, o con algunas “palabras sabias” en cuanto a lo que necesito hacer, o pensar, o algo así. Esta ha sido una piedra muy grande en el camino y me gustaría superarla: /.

(Regresaré en 30 minutos)

Me encantó el pseudo-código! Algunos buenos pensamientos allí, pero todavía no estás ordenando tu progtwig correctamente.

Como usted mismo dijo, no puede leer el texto, retroceder e imprimir una X en una fila en particular. Si establecemos que no se puede hacer, entonces no hay más remedio que conocer todos los valores del histogtwig de antemano.

Así que debes pensar que tu progtwig tiene dos partes (y harás este tipo de división en prácticamente todos los progtwigs que escribas): primero, una parte que hará cálculos; y luego una parte que los emitirá en un determinado formato (el histogtwig).

¡Este consejo te ayudará a empezar! Si necesitas más ayuda, comenta abajo.

Le sugiero que simplifique el problema resolviéndolo para el caso de una palabra por línea, para que pueda usar fgets . Aquí es cómo “comen” las líneas que son demasiado largas .

Luego, tan a menudo, la estructura de datos central es la clave para resolver el problema. La estructura de datos que necesita es una matriz utilizada como tabla de frecuencias:

 int freq[11]; 

En freq[1] , almacene el número de palabras / líneas de longitud 1, en freq[2] las de longitud 2, etc., y en freq[0] las de longitud> 10. No necesita almacenar las palabras ya que el rest del progtwig solo necesita su longitud. Escribir el histogtwig debería ser fácil ahora.

Espero que esto no sea tanto un spoiler.

El siguiente código imprime un histogtwig horizontal utilizando solo el kit de herramientas básico proporcionado hasta ahora por el libro:

 #include /* Prints a horizontal histogram of the lengths of words */ #define MAX_WORDS 100 #define IN 1 #define OUT 0 main() { int c, length, wordn, i, j, state, lengths[MAX_WORDS]; wordn = length = 0; state = OUT; for (i = 0; i < MAX_WORDS; ++i) lengths[i] = 0; while ((c = getchar()) != EOF && wordn < MAX_WORDS) { if (c == ' ' || c == '\t' || c == '\n') state = OUT; else if (wordn == 0) { state = IN; ++wordn; ++length; } else if (state == IN) ++length; else if (state == OUT) { lengths[wordn] = length; ++wordn; length = 1; state = IN; } } lengths[wordn] = length; for (i = 1; i <= wordn; ++i) { printf("%3d: ",i); for (j = 0; j < lengths[i]; j++) putchar('-'); putchar('\n'); } } 
 #include #define RESET 0 #define ON 1 main() { int i,wnum=0,c,wc[50]; int count=0,state; state=RESET; for(i=0;i<50;++i) wc[i]=0; /*Populating the array with character counts of the typed words*/ while((c=getchar())!=EOF) { if(c=='\n'||c=='\t'||c==' '||c=='"') { if(state!=RESET) state=RESET; } else if((c>=65&&c<=90)||(c>=97&&c<=122)) { if(state==RESET) { count=RESET; ++wnum; state=ON; } ++count; wc[wnum-1]=count; } } c=RESET; /*Finding the character count of the longest word*/ for(i=0;i0;--i) { for(count=0;count 

ORIENTACIÓN VERTICAL: Usando solo las herramientas que hemos aprendido hasta ahora en el libro. Y puedes cambiar el tamaño de la matriz, wc [50]. Mantuve el código válido por 50 palabras. La orientación horizontal debería ser bastante más simple. Aunque no lo intenté.

Para hacer un histogtwig de la longitud de las palabras, necesitará conocer las longitudes de las palabras.

  • ¿Cómo se define una palabra?
  • ¿Cómo puedes medir la longitud de una palabra? ¿Puede hacerlo de un carácter a la vez mientras lee la transmisión, o debería almacenar en la entrada un strtok uso o algo similar?

Deberá acumular datos sobre el número de ocurrencias de cada longitud.

  • ¿Cómo almacenarás estos datos?

Tendrá que dar salida a los resultados en una forma agradable. Esto es complicado pero no duro.

Voy a vincular la respuesta a continuación, pero ya que pidió detalles, la clave parece ser esta

Use un ARRAY de longitudes, es decir, tenga una matriz con cada elemento inicializado a cero, suponiendo que la longitud de palabra MAX sea aproximadamente 30 …

* tener una bandera mientras está en la palabra e incrementar un contador cada vez que NO se encuentre un espacio en blanco

* una vez fuera de la palabra, la bandera se establece en “fuera” y el elemento del índice de longitud de palabra correspondiente en la matriz se incrementa, es decir, si el contador de longitud de palabra es w_ctr uso

 array[w_ctr]++ 

* use la matriz como una tabla de referencia para cada línea en un bucle para imprimir cada línea en el histogtwig para que pueda usar la matriz y ahora podrá determinar el clima en el que se insertará o no la ‘X’ en el histogtwig

EDITAR: lo siento, no leí la pregunta correctamente, pero la idea es más simple para los histogtwigs verticales y se puede usar la misma cosa.

después del último paso, simplemente imprima el histogtwig horizontal hasta que el contador exceda la longitud de palabra actual que se está imprimiendo

 for(ctr=0;ctr 

Fin


el original está aquí http://users.powernet.co.uk/eton/kandr2/krx113.html

CLC-wiki es también un lugar, vea los comentarios para más detalles.

 //This is for horizontal histogram. //It works for any number of lines of words where total words <= MAX #include  #define MAX 100 //Change MAX to any value.But dont give words more than MAX. void main() { int w, nwords[MAX] = {0}, i = 0; //nwords is an array for storing length of each word.Length of all words initialized to 0. while ((w = getchar()) != EOF) { if (w == ' ' || w == '\t' || w == '\n') ++i; //if space or tab or newline is encountered, then index of array is advanced indicating new word else ++nwords[i]; //increment the count of number of characters in each word } //After this step,we will have array with each word length. for (i = 0; i < MAX; i++) //iterating through array { printf("\n"); for (; nwords[i] > 0; nwords[i]--) printf("$"); //if length of word > 0 , print $ and decrement the length.This is in loop. if (nwords[i+1] == 0) //as MAX is 100, to avoid printing blank new lines in histogram,we check the length of next word. break; //If it is 0, then break the loop printf("\n"); //After each word bar in histogram, new line. } printf("\n"); } //main 

Debes separar tus 2 problemas en funciones, como:

 void gethist(char *s, int *hist, int len) { /* words here breaks on spaces (' ') */ char *t; for( t=strtok(s," ");t;t=strtok(0," ") ) if(*t) hist[ strlen(t)>len-1?len-1:strlen(t)-1 ]++; } void outhist(int *hist, int len) { int i; for( i=1; i<=len; ++i ) { char *s = calloc(1,5+hist[i-1]); sprintf(s,"%03d|", i); memset( s+4, 'X', hist[i-1]); puts(s); free(s); } } 

entonces es fácil en su principal:

 int main(void) { int c, hist[11] = {}; char *s = calloc(1,1); while ((c = getchar()) != EOF) { s = realloc( s, 2+strlen(s) ); s[ strlen(s)+1 ] = 0; s[ strlen(s) ] = c; } gethist(s,hist,11); free(s); outhist(hist,11); return 0; } 

El histogtwig vertical puede imprimirse una línea a la vez, pasando por la matriz de longitudes de palabra y disminuyendo la longitud de palabra en cada iteración. Se imprime un # si la longitud de la palabra sigue siendo superior a cero, y se imprime un espacio cuando llega a 0. La nueva línea se imprime después de cada iteración.

Si la longitud [i] contiene el número de caracteres de la palabra i, y wordn es el número total de palabras, lo siguiente imprimirá el histogtwig vertical:

 #define YES 1 #define NO 0 more_lines = YES; while (more_lines) { more_lines = NO; for (i = 1; i <= wordn; ++i) { if (lengths[i] > 0 ) { more_lines = YES; printf("#\t"); --lengths[i]; } else printf(" \t"); } putchar('\n'); } 

El código completo está abajo:

 #include /* Prints a histogram of the lenghts of words */ #define MAX_WORDS 100 #define IN 1 #define OUT 0 #define YES 1 #define NO 0 main() { int c, length, wordn, i, j, state, more_lines, lengths[MAX_WORDS]; wordn = length = 0; state = OUT; for (i = 0; i < MAX_WORDS; ++i) lengths[i] = 0; while ((c = getchar()) != EOF && wordn < MAX_WORDS) { if (c == ' ' || c == '\t' || c == '\n') state = OUT; else if (wordn == 0) { state = IN; ++wordn; ++length; } else if (state == IN) ++length; else if (state == OUT) { lengths[wordn] = length; ++wordn; length = 1; state = IN; } } lengths[wordn] = length; /* Print histogram header */ for (i = 1; i <= wordn; ++i) printf ("%d\t", i); putchar('\n'); more_lines = YES; while (more_lines) { more_lines = NO; for (i = 1; i <= wordn; ++i) { if (lengths[i] > 0 ) { more_lines = YES; printf("#\t"); --lengths[i]; } else printf(" \t"); } putchar('\n'); } } 

Aunque el ejercicio se basa en matrices, intenté escribirlo utilizando el bucle while básico y una sentencia if. No soy muy bueno con Arrays a partir de ahora, así que pensé en probar esto. Sin embargo, no lo he probado para detectar errores, pero parece que funciona bien para la mayoría de las entradas.

  #include main() { long int c; while((c=getchar())!=EOF) { if(c!=' '&&c!='\n'&&c!='\t') { putchar("*"); } if(c==' '||c=='\n'||c=='\t') { putchar('\n'); } } return 0; } 

Tenga en cuenta que este es un código muy básico para imprimirlo horizontalmente, solo para la comprensión básica de la estructura.

 // Histogram to print the length of words in its input #include  main() { int wordcount[10],c,token=0; int word=0, count =0; for (int i=0; i<10; i++) { wordcount[i]=0; } while((c=getchar())!=EOF) { if(c== ' ' || c == '\n' || c== '\t') { // add the length of word in the appropriate array number switch(word) { case 1: ++wordcount[0];break; case 2: ++wordcount[1];break; case 3: ++wordcount[2];break; case 4: ++wordcount[3];break; case 5: ++wordcount[4];break; case 6: ++wordcount[5];break; case 7: ++wordcount[6];break; case 8: ++wordcount[7];break; case 9: ++wordcount[8];break; case 10: ++wordcount[9];break; } word =0; } else if (c != ' ' || c != '\n' || c!= '\t') { word++; } } for (int j=0; j<10; j++) { if(wordcount[j]==0) { printf("- "); } for (int k=0;k