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.
Warning: the answers on these pages are crowdsourced, open to anybody to provide/edit after free sign-up, have not all been vetted, might not be correct, let alone optimal, and should not be assumed to be.
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): ********









