TheBlueCat
TheBlueCat

Reputation: 1195

What ways (using stdio) can I print a vertical histogram

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

Answers (6)

Tiến Nguyễn
Tiến Nguyễn

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

Jamie Sandell
Jamie Sandell

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

Vikas Verma
Vikas Verma

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);
} 

Output of program

Upvotes: 1

BLUEPIXY
BLUEPIXY

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

Maxime Ch&#233;ramy
Maxime Ch&#233;ramy

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

Emil Lundberg
Emil Lundberg

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

Related Questions