Reputation: 1195
I'm doing all the K&R exercises and I have finally been able to print a horizontal histogram. It look awful too, but I'll let you judge it. I have not been able to print a histogram of the lengths of words in its input vertically.
How can I modify my program to do this?
Question: Write a program to print a histogram of the lengths if words in its input. It is easy to draw the histogram with the bars horizontal; a vertical orientation is more challenging.
histogram.c
#include <stdio.h>
#define MAX 10
#define IN 1
#define OUT 0
int main()
{
int c, len, state;
int nlength[MAX];
c = len = 0;
state = 1;
for(int i = 0; i < 10; ++i)
nlength[i] = 0;
while ((c = getchar()) != EOF) {
++len;
if (c == ' ' || c == '\n' || c == '\t') {
--len;
state = OUT;
}
if(state == OUT) {
if(len != 0 && len <= MAX)
++nlength[len];
len = 0;
state = IN;
}
}
for (int i = 0; i <= MAX; ++i) {
printf("%d ", i);
for (int a = 0; a < nlength[i]; ++a)
printf("*");
printf("\n");
}
return 0;
}
OUTPUT:
./histogram < histogram.c
0
1 *************************************
2 *************************
3 **************
4 ************
5 *****
6 ******
7 ****
8 **
9 *
10 ***
Upvotes: 0
Views: 8379
Reputation: 1
I know this is an old question but I realize that your code had been wrong about the lengths of words. The result which I run your code is showed below The result after trying your code
I typed in five characters with 1 length, two chars with 2 lengths.... The problem here is your code keep adding while the program actually get to the end of word. With this problem I also manipulated to fix it. My solution is showed
len=setst=0;
state=OUT;
while((c=getchar())!=EOF)
{
if(c==' '||c=='\n'||c=='\t')
{
state=OUT;
if(setst==1)
{
if (len!=0 && len<=MAX)
++nlength[len];
len=0;
setst=0;
}
}
else if (state==OUT)
{
++len;
setst=1;
}
}
The result is clear now. Hope that illustration is clear
Any way thanks a lot about your question. I feel excited about solved something fun and hard.
Upvotes: 0
Reputation: 1
#include <stdio.h>
#define MAX_WORDS 10
//Prints a histogram of the lengths of words in its input
int main()
{
int c, numberOfCharacters, numberOfWords, wordLengthsIndex, largestWordLength;
c = numberOfCharacters = numberOfWords = wordLengthsIndex = largestWordLength = 0;
int wordLengths[MAX_WORDS];
//Read the words
while ( ((c = getchar()) != EOF) && numberOfWords < MAX_WORDS)
{
if (c == ' ' || c == '\n' || c == '\t') //no longer in a word
{
if (numberOfCharacters > largestWordLength)
{
largestWordLength = numberOfCharacters;
}
wordLengths[wordLengthsIndex] = numberOfCharacters;
numberOfCharacters = 0; //reset for the next word
numberOfWords++;
wordLengthsIndex++;
}
else //treat anything else as a character in a word
{
numberOfCharacters++;
}
}
//Print the histogram horizontally
for (int numberOfWordsIndex = 0; numberOfWordsIndex < numberOfWords; ++numberOfWordsIndex)
{
for (int numberOfCharactersIndex = 0; numberOfCharactersIndex < wordLengths[numberOfWordsIndex]; ++numberOfCharactersIndex)
{
putchar('*');
}
putchar('\n');
putchar('\n');
}
//Print the histogram vertically
for (int character = largestWordLength; character > 0; --character) //cycle each row
{
for (int word = 0; word < numberOfWords; ++word) //cycle each column
{
if (wordLengths[word] >= character) //this particular word length falls within the current row
{
putchar('*');
putchar('\t');
}
else
{
putchar(' ');
putchar('\t');
}
}
putchar ('\n');
}
return 0;
}
Upvotes: -1
Reputation: 3706
//vertical HISTOGRAM2
#include<stdio.h>
#include<stdlib.h>
int main()
{
int c,i,j,arr[10],height=0;
system("clear");
for(i=0 ; i<10 ; i++)
arr[i]=0;
while( ( c=getchar() ) != EOF)
{
if(c >= '0' || c <='9')
++arr[c-'0'];
if( arr[c-'0'] > height )
{
height = arr[c-'0'];
}
}
printf("\n");
for(j=height ; j>0 ; j--) // row
{
printf("%2d|",j);
for ( i=0 ; i<=9 ; i++) // column
{
if( j == arr[i] )
{
printf(" *|");
arr[i]--;
}
else
printf(" |");
}
printf("\n");
}
printf(" |");
for ( i=0 ; i<=9 ; i++)
printf(" %d|",i);
printf("\n ------------DIGITS-------------");
printf("\n");
return(0);
}
Upvotes: 1
Reputation: 40145
#include <stdio.h>
#define MAX 10
#define IN 1
#define OUT 0
int main(void){
int c, len, state;
int nlength[MAX];
c = len = 0;
state = IN;
for(int i = 0; i < MAX; ++i)
nlength[i] = 0;
while ((c = getchar()) != EOF) {
++len;
if (c == ' ' || c == '\n' || c == '\t') {
--len;
state = OUT;
}
if(state == OUT) {
if(len != 0 && len <= MAX)
++nlength[len-1];
len = 0;
state = IN;
}
}
int max = 0;
//horizontal
for (int i = 0; i < MAX; ++i) {
if(max < nlength[i]) max = nlength[i];
printf("%2d ", i+1);
for (int a = 0; a < nlength[i]; ++a)
printf("*");
printf("\n");
}
printf("\n");
//vertical
for (int i = max; i > 0; --i){
for (int j = 0; j < MAX; ++j)
if(nlength[j]>=i)
printf("%c ", '*');
else
printf("%c ", ' ');
printf("\n");
}
for(int i=1;i<=MAX;++i)
printf("%-2d", i);
return 0;
}
Upvotes: 0
Reputation: 18821
First you need to know the height of the histogram which is the maximum value. Then you print each row and you decide to put a *
or a according to the value.
int h_max = 0;
for (int a = 0; a < MAX; a++) {
if (h_max <= nlength[a]) h_max = nlength[a];
}
for (int i = h_max; i >= 0; i--) {
for (int a = 0; a < MAX; ++a) {
if (nlength[a] > i) {
printf("*");
} else {
printf(" ");
}
}
printf("\n");
}
Another solution is to print horizontally into an array and print the array in the direction you want.
Upvotes: 3
Reputation: 7379
Let the number of rows be equal to the highest bin value (or some other suitable function of the bin values). Print the histogram one row at a time, for each column make a decision on whether to print a *
in this column on this row or not, based on the bin value corresponding to that column.
Upvotes: 1