KNR C exercise 1-14 implementation with some really cool optimization and tricks.
This commit is contained in:
parent
207fe60c5b
commit
cff9570b57
1 changed files with 80 additions and 0 deletions
80
KNR C/ex1_14.c
Normal file
80
KNR C/ex1_14.c
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/*Initial implementation of KNR C Exercise 1-14*/
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
|
||||||
|
/*Reference array that stores literal characters to be searched later by a
|
||||||
|
* for loop, obtaining their position in the array, and therefore knowing
|
||||||
|
* what position to add them to in charCount without needing a special case
|
||||||
|
* for every possible character. While it is possible to exploit the ascii
|
||||||
|
* table to do this procedurally, this is faster by virtue of initializing
|
||||||
|
* at compile time rather than run time*/
|
||||||
|
int refTable [27] = { ' ' , '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'};
|
||||||
|
|
||||||
|
/*Initialize an array of labels for the numerical table later. This looks
|
||||||
|
* wierd since it's mostly refTable[] again, but again, we do this at
|
||||||
|
* copile rather than procedurally in order to avoid adding an extra if
|
||||||
|
* statement on the print loop to look for the specific case where i is
|
||||||
|
* 0 or 27 and print a different character that isn't in refTable*/
|
||||||
|
/*TODO find a way to do this so that # and ! are replaced by WSPC and PCTN
|
||||||
|
* respectively*/
|
||||||
|
int printTable [28] = { '#' , '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' , '!'};
|
||||||
|
|
||||||
|
/*Initialize character count storage array. Whitespaces are stored at pos 0
|
||||||
|
* while letters are stored at their numeric positions in the alphabet, and
|
||||||
|
* punchtuation is stored at position 27.*/
|
||||||
|
int charCount[28] = { 0 };
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*Begin input text enumeration loop...*/
|
||||||
|
for(int a = getchar(); a != EOF; a = getchar()){
|
||||||
|
/*Begin whitespace filter check*/
|
||||||
|
if(a == '\n' || a == ' ' || a == '\t'){
|
||||||
|
++ charCount[0];
|
||||||
|
continue; /*Escape and restart loop to avoid running redundant
|
||||||
|
tests.*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Begin refTable search loop; check if a = current pos in the refTable
|
||||||
|
* array, increment that position in charCount[], otherwise, increment
|
||||||
|
* i and check again. In any case, break on condition met or value i
|
||||||
|
* out of expected range.*/
|
||||||
|
for(i = 1; i <= 27; ++i){
|
||||||
|
if(a == refTable[i]){
|
||||||
|
++charCount[i];
|
||||||
|
break;
|
||||||
|
} else if(i == 27){
|
||||||
|
++charCount[27]; /*Increments charCount[27] on unspecified char
|
||||||
|
thus preventing hangs on unspecified input*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*Input text enumeration complete; set values in refTable for printing...*/
|
||||||
|
|
||||||
|
|
||||||
|
/*Begin output generation...*/
|
||||||
|
/*Vertical table of numerical values:*/
|
||||||
|
for(int i=0; i <= 27; ++i)
|
||||||
|
printf("%4c %4d\n", printTable[i], charCount[i]);
|
||||||
|
|
||||||
|
/*Print a histogram of gathered data (recycled from ex1_13_improved.c.*/
|
||||||
|
i = 0;
|
||||||
|
printf("\nHistogram of letters encountered.\n");
|
||||||
|
for (int b = charCount[i]; i <= 27; ++i){
|
||||||
|
printf ("%1c ", printTable[i]);
|
||||||
|
for (; b > 0; --b){
|
||||||
|
printf("|");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
b = charCount[(i + 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue