1.13b Escriba un programa que imprima el histograma de las longitudes de palabras de su entrada. Es fácil dibujar el histograma con las barras horizontales; la orientación vertical es un reto más interesante.
_____________________________________________________________________________________
Solución:
Este programa recibe una cadena de caracteres, cuenta la frecuencia de los caracteres de cada palabra y los imprime como un histograma vertical. Esta versión es un poco más difícil de hacer que la anterior, Kernighan_Ritchie_1.13 en la cual el histograma se imprime horizontalmente:
Introduzca una cadena y se imprimira un histograma con el numero de caracteres. de cada palabra (ctl D) para terminar Esta es una cadena para probar el programa Numero de palabra es: 8 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
A continuación se presenta el código:
/* Este programa imprime el histograma de las longitudes de las palabras de su entrada*/ #include <stdio.h> #define Tamano_Arreglo 100 main() { printf("\nIntroduzca una cadena y se imprimira un histograma con el numero de caracteres.\n"); printf("de cada palabra (ctl D) para terminar\n"); int c; //Se leera caracter por caracter. int i; // i es el contador del ciclo for (aparentemente no se puede //definir dentro del cilo for) int s; // s es el contador de un ciclo for int numero_palabra = 1; // Se asume como uno el contador de palabras int longitud_palabra_mas_larga = 0; int palabra_mas_larga = 0; int caracteres[Tamano_Arreglo + 1] = { 0, 0 }; //Al inicializar a 0 los // primeros elementos del arreglo se inicializan todos. while ( (c = getchar()) != EOF) { if( c == '\t' || c == '\n' || c == ' ' ) /* Si se encuentra un espacio, entonces se considera que se ha iniciado una nueva palabra */ { if (longitud_palabra_mas_larga < caracteres[numero_palabra]) { longitud_palabra_mas_larga = caracteres[numero_palabra]; palabra_mas_larga = numero_palabra; } numero_palabra++; } else caracteres[numero_palabra]++; // Si no es un espacio, se incrementa el numero de caracteres // de la palabra actual } printf("Numero de palabra es: %d ", numero_palabra - 1); printf("\n\n"); for ( s = longitud_palabra_mas_larga; s >= 1; s-- ) { for ( i = 1; i <= numero_palabra; i++ ) { if ( caracteres[i] >= s ) printf("* "); else printf(" "); } printf("\n"); } printf("\n"); return 0; }
_____________________________________________________________________________________________
Esta entrada es parte de los problemas resueltos del libro El Lenguaje de Programación C, de B. Kernighan y D. Ritchie.
Entrada Anterior
Entrada Siguiente
Porfa explica mejor este si bien el otro de casulaidad lo entendi (no me quedo muy claro el ciclo) este menos jajajajaja
ResponderEliminarsi c no es un espacio,tabulacion o nueva linea, entonces el arreglo caracteres[1] (numero_palabra=1) ira aumentando aumentando su valor hasta que c sea un espacio o tabulacion o nueva linea, en ese momento se compara si la longitud de la palabra mas larga(valor=0) es menor al valor de caracteres[1] (es decir, la cantidad de 'letras' leidas hasta el momento), entonces si resulta verdad, longitud_palabra_mas_larga toma el valor de arreglo caracteres[1], para luego aumentar en 1 el valor de numero_palabra, que en ese entonces era 1 sera ahora 2, por lo que contara la cantidad de los nuevos caracteres a leer y los guardara en caracteres[2] (como en el principio de caracteres[1] ) y asi hasta que c=EOF o -1 v:
Eliminarel primer bucle for inicia con el ultimo valor de longitud_palabra_mas_larga(ya que a s se le asigna ese valor :v), el cual va a decrecer hasta llegar a 1, en el segundo bucle for primero verifica si i=1 es menor a la cantidad de palabras leidas hasta el momento,luego pasa al if y se verifica si el valor que contiene caracteres[i] (i=1) es mayor o igual a s (la longitud de la palabra mas larga), si es verdad, entonces se imprime un asterisco, al avanzar/aumentar i en 2, se ve si el valor de caracteres[2] es mayor o igual a s ,en caso de que sea menor, se imprime u vacio o espacio. Si i es mayor a la cantidad de palabras, se sale del segundo bucle for y se imprime una nueva linea,y se sigue en el primer bucle, pero con el valor decrementado de s(por ejemplo s empezo con 5 y ahora tiene el valor de 4 v:) y se inicia de nuevo el segundo bucle y se imprime los asteriscos hasta que s sea 1 y acaba el programa :v
PD: La variable palabra mas larga es inutil en este programa :v