The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 1.14 on page 24
Write a program to print a histogram of the frequencies of different characters in its input.
Solution by Liron Abutbul (Horizontal Edition)
/** * Write a program to print a histogram of the frequencies of different characters in its input. */ #include <stdio.h> #define ASCII 128 // number of ASCII characters int main(void) { int c, i, j, max_freq = 0; int freq[ASCII]; // frequency of the characters for(i = 0; i < ASCII; freq[i++] = 0); // initialize the array /** * Count the frequency of the characters in the input */ while((c = getchar()) != EOF) { if(c != ' ' && c != '\n' && c != '\t') freq[c]++; } /** * Determine the maximum frequency of the characters */ for(i = 0; i < ASCII; i++) { if(freq[i] > max_freq) max_freq = freq[i]; } printf("Histogram of the frequencies of different characters in its input:\n"); /** * Print the y-axis of the histogram with the characters */ for(i = 0; i < ASCII; i++) { if(freq[i] > 0) { printf("%c | ", i); for(j = 0; j < freq[i]; j++) printf("\u25A0 "); printf("\n"); } } /** * Print the x-axis of the histogram with the frequency of the characters */ printf(" +"); for(i = 1; i <= max_freq; i++) // print the horizontal line printf("———"); printf("\nW/F "); // print the label of the x-axis (Frequency/Length) for(i = 1; i <= max_freq; i++) // print the frequency of the characters printf("%02d ", i); return 0; }
! | ■ ■ # | ■ $ | ■ ■ ■ ( | ■ ■ * | ■ ■ + | ■ , | ■ ; | ■ @ | ■ ■ ■ [ | ■ ■ _ | ■ a | ■ ■ ■ ■ ■ ■ ■ ■ d | ■ ■ ■ ■ ■ ■ e | ■ ■ f | ■ ■ ■ g | ■ i | ■ ■ j | ■ ■ k | ■ l | ■ s | ■ ■ ■ ■ ■ ■ v | ■ w | ■ ■ +———————————————————————— W/F 01 02 03 04 05 06 07 08
Solution by Vidhan Gupta
/* Write a prgram to print a histogram of the frequencies of different characters in its input. */ #include <stdio.h> int main() { char histogram[94]; int c, i, j; for (i = 0; i < 95; ++i) histogram[i] = 0; while ((c = getchar()) != EOF) if (c >= 32 || c <= 95) ++histogram[c - 32]; int maximum = histogram[0]; for (i = 0; i < 95; ++i) if (histogram[i] > maximum) maximum = histogram[i]; for (i = maximum; i > 0; --i) { printf("%4d|", i); for (j = 0; j < 95; ++j) { if (histogram[j] == i) { putchar('*'); --histogram[j]; } else putchar(' '); } putchar('\n'); } printf(" +"); for (i = 0; i < 95; i++) putchar('-'); printf("\n "); for (i = 32; i <= 126; ++i) putchar(i); putchar('\n'); return 0; }
INPUT: Random Bullshit GO! :- iofowhugweghoasifh9f2u3840536y579u 21490''råtgweg¨@afgbsfba@@**@@**OWPFOUEWFHARGJOSUGFHEGEBUOSEHFWg¨@@¨ ¨ëgpergo4p58350643569+3405850871049tu45y84560349687u45036uy904554u504 5y34t0et(=)$="(#%$/#()=)?%$#`?=)I^~~~±[][]{)(}{}{}{}{sejrgaigjhgojfg OUTPUT: 14| ** 13| ** 12| ** * 11| * ** * 10| * ** * 9| * ** * 8| * *** * * 7| * *** * * * * 6| * **** ** * ** * * 5| * * **** ** * * * **** * ** * 4|* *** * **** ** * * *** * * ***** * *** * * * 3|* ** *** * ******* * * **** * * * * ****** * **** * * * ** 2|* *** **** ********** * ** * **** * ** * * * * ** ****** * ** **** * * * ** 1|****** ***** * ************ * **** ****** ** ** * * * ** *** ******* ***** **** * * * ** +----------------------------------------------------------------------------------------------- !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Solution by Richard Heathfield (Category 0)
Naturally, I've gone for a vertical orientation to match exercise 13. I had some difficulty
ensuring that the printing of the X-axis didn't involve cheating. I wanted to display each
character if possible, but that would have meant using isprint(), which we haven't yet met.
So I decided to display the value of the character instead. (The results below show the
output on an ASCII system - naturally, a run on an EBCDIC machine would give different numbers.)
I had to jump through a few hoops to avoid using the % operator which, again, we haven't yet
met at this point in the text.
#include <stdio.h> /* NUM_CHARS should really be CHAR_MAX but K&R haven't covered that at this stage in the book */ #define NUM_CHARS 256 int main(void) { int c; long freqarr[NUM_CHARS + 1]; long thisval = 0; long maxval = 0; int thisidx = 0; for(thisidx = 0; thisidx <= NUM_CHARS; thisidx++) { freqarr[thisidx] = 0; } while((c = getchar()) != EOF) { if(c < NUM_CHARS) { thisval = ++freqarr[c]; if(thisval > maxval) { maxval = thisval; } } else { thisval = ++freqarr[NUM_CHARS]; if(thisval > maxval) { maxval = thisval; } } } for(thisval = maxval; thisval > 0; thisval--) { printf("%4d |", thisval); for(thisidx = 0; thisidx <= NUM_CHARS; thisidx++) { if(freqarr[thisidx] >= thisval) { printf("*"); } else if(freqarr[thisidx] > 0) { printf(" "); } } printf("\n"); } printf(" +"); for(thisidx = 0; thisidx <= NUM_CHARS; thisidx++) { if(freqarr[thisidx] > 0) { printf("-"); } } printf("\n "); for(thisidx = 0; thisidx < NUM_CHARS; thisidx++) { if(freqarr[thisidx] > 0) { printf("%d", thisidx / 100); } } printf("\n "); for(thisidx = 0; thisidx < NUM_CHARS; thisidx++) { if(freqarr[thisidx] > 0) { printf("%d", (thisidx - (100 * (thisidx / 100))) / 10 ); } } printf("\n "); for(thisidx = 0; thisidx < NUM_CHARS; thisidx++) { if(freqarr[thisidx] > 0) { printf("%d", thisidx - (10 * (thisidx / 10))); } } if(freqarr[NUM_CHARS] > 0) { printf(">%d\n", NUM_CHARS); } printf("\n"); return 0; }
Here's the output of the program when given its own source as input:
474 | * 473 | * 472 | * 471 | * 470 | * 469 | * 468 | * 467 | * 466 | * 465 | * 464 | * 463 | * 462 | * 461 | * 460 | * 459 | * 458 | * 457 | * 456 | * 455 | * 454 | * 453 | * 452 | * 451 | * 450 | * 449 | * 448 | * 447 | * 446 | * 445 | * 444 | * 443 | * 442 | * 441 | * 440 | * 439 | * 438 | * 437 | * 436 | * 435 | * 434 | * 433 | * 432 | * 431 | * 430 | * 429 | * 428 | * 427 | * 426 | * 425 | * 424 | * 423 | * 422 | * 421 | * 420 | * 419 | * 418 | * 417 | * 416 | * 415 | * 414 | * 413 | * 412 | * 411 | * 410 | * 409 | * 408 | * 407 | * 406 | * 405 | * 404 | * 403 | * 402 | * 401 | * 400 | * 399 | * 398 | * 397 | * 396 | * 395 | * 394 | * 393 | * 392 | * 391 | * 390 | * 389 | * 388 | * 387 | * 386 | * 385 | * 384 | * 383 | * 382 | * 381 | * 380 | * 379 | * 378 | * 377 | * 376 | * 375 | * 374 | * 373 | * 372 | * 371 | * 370 | * 369 | * 368 | * 367 | * 366 | * 365 | * 364 | * 363 | * 362 | * 361 | * 360 | * 359 | * 358 | * 357 | * 356 | * 355 | * 354 | * 353 | * 352 | * 351 | * 350 | * 349 | * 348 | * 347 | * 346 | * 345 | * 344 | * 343 | * 342 | * 341 | * 340 | * 339 | * 338 | * 337 | * 336 | * 335 | * 334 | * 333 | * 332 | * 331 | * 330 | * 329 | * 328 | * 327 | * 326 | * 325 | * 324 | * 323 | * 322 | * 321 | * 320 | * 319 | * 318 | * 317 | * 316 | * 315 | * 314 | * 313 | * 312 | * 311 | * 310 | * 309 | * 308 | * 307 | * 306 | * 305 | * 304 | * 303 | * 302 | * 301 | * 300 | * 299 | * 298 | * 297 | * 296 | * 295 | * 294 | * 293 | * 292 | * 291 | * 290 | * 289 | * 288 | * 287 | * 286 | * 285 | * 284 | * 283 | * 282 | * 281 | * 280 | * 279 | * 278 | * 277 | * 276 | * 275 | * 274 | * 273 | * 272 | * 271 | * 270 | * 269 | * 268 | * 267 | * 266 | * 265 | * 264 | * 263 | * 262 | * 261 | * 260 | * 259 | * 258 | * 257 | * 256 | * 255 | * 254 | * 253 | * 252 | * 251 | * 250 | * 249 | * 248 | * 247 | * 246 | * 245 | * 244 | * 243 | * 242 | * 241 | * 240 | * 239 | * 238 | * 237 | * 236 | * 235 | * 234 | * 233 | * 232 | * 231 | * 230 | * 229 | * 228 | * 227 | * 226 | * 225 | * 224 | * 223 | * 222 | * 221 | * 220 | * 219 | * 218 | * 217 | * 216 | * 215 | * 214 | * 213 | * 212 | * 211 | * 210 | * 209 | * 208 | * 207 | * 206 | * 205 | * 204 | * 203 | * 202 | * 201 | * 200 | * 199 | * 198 | * 197 | * 196 | * 195 | * 194 | * 193 | * 192 | * 191 | * 190 | * 189 | * 188 | * 187 | * 186 | * 185 | * 184 | * 183 | * 182 | * 181 | * 180 | * 179 | * 178 | * 177 | * 176 | * 175 | * 174 | * 173 | * 172 | * 171 | * 170 | * 169 | * 168 | * 167 | * 166 | * 165 | * 164 | * 163 | * 162 | * 161 | * 160 | * 159 | * 158 | * 157 | * 156 | * 155 | * 154 | * 153 | * 152 | * 151 | * 150 | * 149 | * 148 | * 147 | * 146 | * 145 | * 144 | * 143 | * 142 | * 141 | * 140 | * 139 | * 138 | * 137 | * 136 | * 135 | * 134 | * 133 | * 132 | * 131 | * 130 | * 129 | * 128 | * 127 | * 126 | * 125 | * 124 | * 123 | * 122 | * 121 | * 120 | * 119 | * 118 | * 117 | * 116 | * 115 | * 114 | * 113 | * 112 | * 111 | * 110 | * 109 | * * 108 | * * 107 | * * 106 | * * 105 | * * 104 | * * 103 | * * 102 | * * 101 | * * 100 | * * 99 | * * 98 | * * 97 |** * 96 |** * 95 |** * 94 |** * 93 |** * 92 |** * 91 |** * 90 |** * 89 |** * 88 |** * 87 |** * 86 |** * 85 |** * 84 |** * 83 |** * 82 |** * 81 |** * 80 |** * 79 |** * 78 |** * 77 |** * 76 |** * 75 |** * 74 |** * 73 |** * 72 |** * 71 |** * * 70 |** * * 69 |** * * 68 |** * * 67 |** * * 66 |** * * 65 |** * * 64 |** * * 63 |** * * 62 |** * * 61 |** * * 60 |** * * 59 |** * * * 58 |** * * * 57 |** * * * 56 |** * * * 55 |** * * * 54 |** * * * 53 |** * * * 52 |** * * * 51 |** ** * * 50 |** ** * * 49 |** ** *** 48 |** ** *** 47 |** ** *** 46 |** ** *** 45 |** ** *** 44 |** ** *** 43 |** * ** *** 42 |** * * * ** *** 41 |** * * * ** *** 40 |** ** * * * ** *** 39 |** ** * * * * ** *** 38 |** ** * * * * ** *** 37 |** ** * * * * ** *** * 36 |** ** * * * * ** *** * 35 |** ** * * * * ** *** * 34 |** ** * * * * ** *** * 33 |** ** * * * * ** *** * 32 |** ** * * * * ** * *** * 31 |** ** * * * * ** * *** * 30 |** ** * * * * ** * *** * 29 |** ** * * * * ** * *** * 28 |** * ** * * *** ** * * *** * 27 |** * ** * * * *** ** * * *** * 26 |** * ** * * * *** ** * * *** * 25 |** * ** * * * *** ** * * *** * 24 |** * ** * * * *** ** * * *** * 23 |** * ** * * * *** ** * * *** * 22 |** * ** * * * *** ** * * *** * 21 |** * ** * * * * *** ** * * *** * * 20 |** * ** * * * * *** ** * * *** * * * * 19 |** * ** * * * * *** ** * * *** * * * * 18 |** * ** * * * * * *** ** * * *** * * * * 17 |** * ** * * * * * *** ** * * *** * * * * 16 |** * ** * * * * * *** ** * ** *** * * * * 15 |** * ** * * * * * * * *** ** * ** *** * * * * 14 |** * ** * * * * ** * * * ** *** ** * *** *** * * * * 13 |** * ** * * * * ** * ** *** ** *** ** * *** *** * * * * 12 |** * ** * * * **** * ** *** ** *** ** * *** *** * * * * 11 |** * ** * * * **** * ** *** * *** *** ** * ******* * * * * 10 |** * ** * * * **** * ** *** * *** *** ** * ******* * * * * 9 |** * ** * * * **** * ** *** * *** *** ** * ******* * * * * 8 |** * ** * * ****** * ** *** * *** *** ** * ******* * * * * 7 |** * ** * ** ****** * ** *** * *** **** ** ********* * * * * 6 |** * ** * *** ****** * ** *** ***** **** ** ********* * * * * 5 |** * * ****** *** ****** * ** *** ***** ******* ********* * * * * 4 |** * * ****** *** ****** * ** *** ***** ******* *********** * * * 3 |** * * ****** *** ****** * ** *** ************* *********** * * * 2 |** *** ****** *** ****** * ** *** ************* *********** * * * 1 |********************************************************************** +---------------------------------------------------------------------- 0000000000000000000000000000000000000000000000111111111111111111111111 1333333344444444445555566666677777788889999999000000000111111111122222 0234578901234567890234901257902578923581235789012345789012345678901345
Solution by Bocchio (Category 0)
This program prints the histogram of characters in the input without taking into account blanks and assuming no character has a frequency over 9999. Also this only works for ASCII input.
#include <stdio.h> /* Creates a histogram with the frequency of the characters in the input */ /* Vertical version */ int main() { int len_freq[94]; int heigth; int c, i, k; heigth = 0; for(i = 0; i <= 93; ++i) len_freq[i] = 0; while((c = getchar()) != EOF){ if(33 <= c && c <= 126){ ++len_freq[c-33]; if(len_freq[c-33] >= heigth) heigth = len_freq[c-33]; } } for(i = heigth; i > 0; --i){ printf("%4d|", i); for(k = 0; k <= 93; ++k){ if(len_freq[k] >= i) printf("#"); else printf(" "); } printf("\n"); } printf(" +"); for(i = 0; i <= 93; ++i) printf("-"); printf("\n "); for(i = 0; i <= 93; ++i){ printf("%c", i+33); } printf("\n"); return 0; }
Here's the output of the program when given its own source as input:
48| # 47| # 46| # 45| # 44| # 43| # 42| # 41| # 40| # 39| # 38| # 37| # 36| # 35| # 34| # 33| # # 32| # # 31| # # 30| # # # # 29| # # # # # 28| # # # # # 27| # # # # # # 26| # # # # # # 25| # ## # # # # 24| # ## # # # # 23| # ## # # # # 22| # ## # # # # 21| ## # ## # # # # 20| ## # ## # # # # 19| ## # ## ## # # # 18| # ## # # ## ## # # # 17| # ## # # ## ## # # # 16| # ## # # ## ## # # # 15| # ## # # ## ## # # # 14| # ## # # # # ## ## # # # 13| # ## # # # # ## ## # # # 12| # ## # # # # # ## ## # # # 11| # ## # # # # # ## ## # # # 10| # ## # # # # # ## ## # # # # # 9| # ## # # # # # ## ## # ### # # 8| # ## # # # # # # # ## ## # ### # # 7| # ## # # # ### # # ##### # ##### # 6| # ## # # # # ### # # # # # ##### # ####### # # 5| # ## # # # # # ### # # # # # ##### ## ####### # # 4| # ###### ## # # #### # # # # # ##### ## ######## # # 3| # ###### ## # # #### ### # # ####### ## ######## # # 2| ## ## ###### ## ## # #### ### # # ####### ########### # # # 1|### ## ############# # # #### # ## # # ### # # ####### ############# # ### +---------------------------------------------------------------------------------------------- !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Solution by mazouzi
Here is a horizontal version
/* The solution to a modified version of excercise 1.14 in the KR2. The original questions asks for a histogram of the frequency of all characters ina a text. This version takes the alphabet characters only. */ #include <stdio.h> #define MAX 122 #define MIN 97 #define DIFF 32 int main(){ int c = EOF; int i, j; int array[MAX - MIN]; for (i = MIN; i <= MAX; i++){ array[i] = 0; } while ((c = getchar()) != EOF){ if (c >= MIN) ++array[c]; else { ++array[c + DIFF]; } } for (i = MIN; i <= MAX; i++){ printf("|%c%c|", i - DIFF, i); for (j = 1; j <= array[i]; j++){ putchar('*'); } putchar('\n'); } return 0; }
/* Below is an example of the program's output. */ /* |Aa|************************************ |Bb|********** |Cc|*************************** |Dd|****************** |Ee|*************************************************************** |Ff|*************** |Gg|********* |Hh|**************** |Ii|************************************************* |Jj| |Kk|**** |Ll|***************************** |Mm|*************************** |Nn|********************************** |Oo|*********************************************************** |Pp|*************** |Qq| |Rr|********************************************** |Ss|**************************************** |Tt|******************************************** |Uu|******************** |Vv|***** |Ww|*** |Xx|** |Yy|******** |Zz|
Solution by scopych
Here is a horizontal version.
This version takes the alphabet characters only.
#include <stdio.h> /* * Program prints a histogram of the frequencies of characters in its input. * A horizontal oriented bars. */ main() { int i , c; int abc [26]; for (i = 0; i < 26; ++i) abc[i] = 0; while ((c = getchar()) != EOF) { if (c > 64 && c < 91) { ++abc[c - 65]; } else if (c > 96 && c < 123) { ++abc[c - 97]; } } printf("number of every character in input \n"); for (i = 0; i < 26; ++i) { printf("%c %4d ", (65 + i), abc[i]); while (abc[i] > 0) { printf("|"); --abc[i]; } printf("\n"); } }
The program's output. number of every character in input A 19 ||||||||||||||||||| B 9 ||||||||| C 23 ||||||||||||||||||||||| D 4 |||| E 18 |||||||||||||||||| F 13 ||||||||||||| G 3 ||| H 9 ||||||||| I 35 ||||||||||||||||||||||||||||||||||| J 0 K 0 L 5 ||||| M 4 |||| N 19 ||||||||||||||||||| O 12 |||||||||||| P 8 |||||||| Q 1 | R 21 ||||||||||||||||||||| S 8 |||||||| T 18 |||||||||||||||||| U 5 ||||| V 1 | W 2 || X 0 Y 1 | Z 1 |
Horizontal histogram of the frequencies of all different characters in its input.
#include <stdio.h> #define ASCIICOUNT 127 int main(){ int c; int chararray[ASCIICOUNT]; int countarray[ASCIICOUNT]; int counter, counter1; for(counter = 0; counter < ASCIICOUNT; ++counter){ countarray[counter] = 0; } counter = 0; for(counter = 0; counter < ASCIICOUNT; ++counter){ chararray[counter] = counter; } counter = 0; while((c = getchar()) != EOF){ if(c != ' ' && c != '\t' && c != '\n'){ ++counter; for(counter1 = 0; counter1 < ASCIICOUNT; ++counter1){ if(chararray[counter1] == c){ ++countarray[counter1]; } } counter1 = 0; } } counter1 = 0; counter = 0; for(counter1; counter1 < ASCIICOUNT; ++counter1){ if(countarray[counter1] != 0){ printf("%c: ",chararray[counter1]); for(counter = 0; counter < countarray[counter1]; ++counter){ putchar('*'); } putchar('\n'); } } }
Solution by CakeOfTrust
A quite grotesque vertical version that might misbehave on small screens. Symbolic constants such as SIZE_H, SIZE_V and HIST_OX_LIM must be modified to avoid "ugly" output. Its Y-axis is 100 by default since it represents % and not the actual amount of characters. It also only displays the characters that are given to it, not the whole set like ASCII.
#include <stdio.h> #define HIST_OY_LIM 100 #define SIZE_H 3 #define SIZE_V 2 #define HIST_OX_LIM 29 #define YES 1 #define NO 0 int main(void) { int c, hist_num[HIST_OX_LIM], free = HIST_OX_LIM, i, new = YES, size_h, size_v; char hist_ch[HIST_OX_LIM]; for (; free > 0; --free) hist_num[free - 1] = hist_ch[free - 1] = 0; while ((c = getchar()) != EOF) { for (i = free; i >= 0 && i < (HIST_OX_LIM); --i) if (hist_ch[i] == c) { ++hist_num[i]; new = NO; } if (new == YES) { hist_ch[free] = c; ++hist_num[free]; ++free; } else new = YES; } i = 0; for (c = 0; i < free; ++i) c += hist_num[i]; putchar('\n'); putchar('\n'); for (new = HIST_OY_LIM; new > 0; --new) { printf("%3d| ", new); for (size_v = SIZE_V; size_v > 0; --size_v) { if (size_v < SIZE_V) { putchar('\n'); putchar(' '); putchar(' '); putchar(' '); putchar('|'); putchar(' '); putchar(' '); } for (i = 0; i < free; ++i) { for (size_h = SIZE_H; size_h > 0; --size_h) if (hist_num[i]*100.0/c >= new*1.0) putchar('#'); else putchar(' '); putchar(' '); } } putchar('\n'); } putchar(' '); putchar(' '); putchar(' '); putchar('|'); for (; i >= 0; --i) for (size_h = SIZE_H + 1; size_h > 0; --size_h) putchar('_'); putchar('\n'); printf(" "); for (++i ; i < free; ++i) if (hist_ch[i] == ' ') { putchar('\''); putchar(' '); putchar('\''); putchar(' '); } else if (hist_ch[i] == '\t') { putchar('\\'); putchar('t'); putchar(' '); putchar(' '); } else if (hist_ch[i] == '\n') { putchar('\\'); putchar('n'); putchar(' '); putchar(' '); } else { putchar(' '); putchar(hist_ch[i]); putchar(' '); putchar(' '); } putchar('\n'); return 0; }
100| | 99| | 98| | 97| | 96| | 95| | 94| | 93| | 92| | 91| | 90| | 89| | 88| | 87| | 86| | 85| | 84| | 83| | 82| | 81| | 80| | 79| | 78| | 77| | 76| | 75| | 74| | 73| | 72| | 71| | 70| | 69| | 68| | 67| | 66| | 65| | 64| | 63| | 62| | 61| | 60| | 59| | 58| | 57| | 56| | 55| | 54| | 53| | 52| | 51| | 50| | 49| | 48| | 47| | 46| | 45| | 44| | 43| | 42| | 41| | 40| | 39| | 38| | 37| | 36| | 35| | 34| | 33| | 32| | 31| | 30| | 29| | 28| | 27| | 26| | 25| | 24| | 23| | 22| | 21| | 20| | 19| | 18| | 17| | 16| | 15| | 14| | 13| | 12| | 11| | 10| | 9| ### ### ### | ### ### ### 8| ### ### ### | ### ### ### 7| ### ### ### ### ### | ### ### ### ### ### 6| ### ### ### ### ### | ### ### ### ### ### 5| ### ### ### ### ### ### | ### ### ### ### ### ### 4| ### ### ### ### ### ### | ### ### ### ### ### ### 3| ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### | ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### 2| ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### | ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### 1| ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### | ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### |____________________________________________________________________________________________ g l f d s , ; ' ' h t ' q w [ ] \n n j k m e a
Solution by [Octavian]
A basic approach.
#include <stdio.h> int main(void) { int c, i, j; int alphabet[25]; int charcount[25]; for (i = 0; i <= 25; ++i) { alphabet[i] = 97 + i; charcount[i] = 0; } while ((c = getchar()) != EOF) for (i = 0; i<= 25; i++) if (c == alphabet[i]) ++charcount[i]; printf("\n"); for (i = 0; i <= 25; ++i) { printf("%c", alphabet[i]); for (j = 1; j <= charcount[i]; ++j) printf("|"); printf("\n"); } printf("\n"); }
a|||| b c||| d e||||||| f|| g| h||| i||||| j k l|| m| n||||| o|||| p|| q r|| s||| t||||| u|| v| w| x| y z
Solution by Marvelcoder
* FrequencyVerticalHistogram.c * * Created on: 01-Aug-2020 * Author: Marvelcoder *
#include<stdio.h> #define WORD_LENGTH 15 int main(){ int character,varray[WORD_LENGTH]={0},i,count,max,temp,visited,barray[WORD_LENGTH]={0},farray[WORD_LENGTH]={0},fqncy,found; i=count=found=max=fqncy=temp=visited=0; while((character=getchar())!=EOF){ if(character!=' '&&character!='\n'&&character!='\t'){ ++count; }else{ if(count!=0){ varray[i]=count; i++; count=0; } } } //Prints the length of each word for(i=0;i<WORD_LENGTH;i++){ printf("%d ",varray[i]); } printf("\n"); /* * This block of code calculates the frequency of each element from one array * and sets it in corresponding location in another array. * * For ex: 5 is at 0th index and it's frequency is 3 * so 3 is set at 0th index in another array. */ for(int i=0;i<WORD_LENGTH;i++){ temp=i; while(temp>=0){ if(varray[i]==varray[--temp]){ visited=1; break; } } if(visited==0){ for(int j=0;j<WORD_LENGTH;j++){ if(varray[i]==varray[j]){ ++fqncy; } } } if(visited==0){ barray[i] = fqncy; fqncy=0; } visited=0; } //Prints the frequency of each word for(i=0;i<WORD_LENGTH;i++){ printf("%d ",barray[i]); } printf("\n"); /* * This block of code calculates the frequency of each element from one array * and sets it in corresponding location in another array. * * For ex: 5 is at 0th index and it's frequency is 3 * so 3 is set at 0th index in another array. */ for(int i=0;i<WORD_LENGTH;i++){ temp=i; while(temp>=0){ if(barray[i]==barray[--temp]){ visited=1; break; } } if(visited==0){ for(int j=0;j<WORD_LENGTH;j++){ if(barray[i]==barray[j]){ ++fqncy; } } } if(visited==0){ farray[i] = fqncy; fqncy=0; } visited=0; } //Prints the frequency of each word for(i=0;i<WORD_LENGTH;i++){ printf("%d ",farray[i]); } //Finds the maximum frequency which will be on Y-axis for(i=0;i<WORD_LENGTH;i++){ if(farray[i] > max){ max = farray[i]; } } printf("\n---------------VERTICAL HISTOGRAM STARTS--------------------\n"); for(i=max;i>0;i--){ printf("%d",i); for(int j=1;j<=11;j++){ found=1; for(int k=0;k<WORD_LENGTH;k++){ if(j==barray[k] && j<11){ if(farray[k]==i){ printf(" X "); --farray[k]; found=0; } }else if(j>10 && farray[k]==i){ printf(" X"); found=0; } } if(found==1){ printf(" "); } } printf("\n\n"); } printf(" "); for(i=1;i<=11;i++){ if(i==11){ printf(">10"); }else{ printf(" %d ",i); } } printf("\n---------------VERTICAL HISTOGRAM ENDS--------------------\n"); return 0; }
Output
---------------VERTICAL HISTOGRAM STARTS-------------------- 4 X 3 X 2 X 1 X X X 1 2 3 4 5 6 7 8 9 10 >10 ---------------VERTICAL HISTOGRAM ENDS--------------------
Solution by Красимир Беров
Yet another simple solution. Formatting of the source code is done using `:%!clang-format` at the Vim command-line while editing the file. The source is compiled and executed with itself as input like this:
TCPL$ time gcc ex114.c -o ex114 && ./ex114 < ./ex114.c
#include <stdio.h> /* Write a program to print a histogram of the frequencies of different * characters in its input. */ #define A 'A' #define z 'z' int main() { /* The index of z minus the index of A gives us the needed length for * the array of characters. */ char letters[z - A], c = EOF, l, i; /* Initialize the count of the letters. */ for (l = A; l < z + 1; ++l) letters[l - A] = 0; while ((c = getchar()) != EOF) { if (c >= A && c <= z) ++letters[c - A]; } for (l = A; l < z + 1; ++l) { /* Print only the used letters. Not using 'continue;' as it is not * mentioned yet in the book. */ if (letters[l - A] != 0) { /* I searched the internet: "How to display characters using * printf?" `man 3 printf` also contains this information in * section 'Conversion specifiers'. */ printf("\n%c (%02d): ", l, letters[l - A]); for (i = 0; i < letters[l - A]; ++i) putchar('*'); } } putchar('\n'); return 0; }
The output is as follows:
real 0m0,044s user 0m0,033s sys 0m0,011s A (12): ************ C (01): * E (02): ** F (02): ** H (01): * I (02): ** N (01): * O (02): ** P (01): * T (01): * W (01): * [ (06): ****** \ (02): ** ] (06): ****** ` (02): ** a (25): ************************* b (01): * c (24): ************************ d (14): ************** e (64): **************************************************************** f (22): ********************** g (07): ******* h (23): *********************** i (50): ************************************************** k (01): * l (27): *************************** m (07): ******* n (44): ******************************************** o (31): ******************************* p (10): ********** q (01): * r (42): ****************************************** s (32): ******************************** t (61): ************************************************************* u (13): ************* v (02): ** w (02): ** x (02): ** y (04): **** z (08): ********