Your code that counts letters is very obscure. For example, this loop
executes only once because of the break statement:
1 2 3 4 5 6 7 8
|
while( index < str.length() )
{
// The character at the index.
int ch = str[index];
// Increment the charCountArray for the letter.
charCountArray[ch-'a']++;
break;
}
|
Simplify the code to:
1 2 3 4 5 6 7 8 9 10 11 12
|
for( unsigned int i = 0; i < str.length(); i++ )
{
int ch = str[i];
if( ch >= 'a' && ch <= 'z' )
{
// Increment the charCountArray for the letter.
charCountArray[ch-'a']++;
} else if( ch >= 'A' && ch <= 'Z' )
{
charCountArray[ch-'A']++;
}
}
|
Now lets start with the printing code:
for ( int i = 1; i <= maxValue; i++ ) // If maxValue=87, you'll print 87 lines?
You're always printing 10 lines so that should be:
for ( int i = 0; i <10; i++ )
Now the code to print the frequency needs to change slightly:
1 2 3 4
|
if( charFreqArray[lett] >= maxValue * i / 10 )
cout << "* ";
else
cout << " ";
|
getStringLength() sets a global variable. You use this global instead
of the return value. That's bad form, but the worse thing about this
code is that it doesn't initialize length. If you call
getStringLength() twice, you'll get different answers. Use a local
variable to get the string length As a habbit, I always call the
return value of a function "result":
1 2 3 4 5 6 7
|
int getStringLength( ) //calculates and returns the total number of alphabets entered
{
int result = 0;
for( int i = 0; i < 26; i++ )
result += charCountArray[i];
return result;
}
|
Then inside main, make length local and assign it to the return value
of getStringLength
int length = getStringLength( );
freqCalculator should take the total number of letters as a
parameter. You're currently modifying the frequency values to make
display easier. Don't do that. Data should represent the actual data:
1 2 3 4 5
|
void freqCalculator(int length)
{
for( int i = 0; i < 26; i++ ) //calculates the frequency percentage
charFreqArray[i] = charCountArray[i]/(double) length * 100;
}
|
You're finding the largest value and then using that to find the index
of the largest value. It's must better to just find the index and then
the largest value is charFreqArray[index]. Again, use local variables
as much as possible and return the actual index:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int findLargestValueIndex( ) //finds the index # for the most frequent letter
{
int maxValue = charCountArray[0];
int result = 0;
for( int i = 0; i < 26; i++ )
{
if( charCountArray[i] >= maxValue )
{
maxValue = charCountArray[i];
result = i;
}
}
return result;
}
|
1 2 3 4 5 6 7
|
for each character on a line
if the character is a letter
for EVERY character on the line
increment the charCountArray[character-'a']
}
}
}
|
Here's the code with all of these changes and things like prototypes fixed to match
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
#include <iostream>
#include <iostream>
#include <string>
using namespace std;
void setCharCountArrayToZero( );
int getStringLength( );
int findLargestValueIndex( );
void freqCalculator(int length );
void printFrequency(double maxValue );
int charCountArray[26];
double charFreqArray[26];
int main()
{
string str;
cout << "Enter text at the prompt to calculate letter frequencies. Enter DONE when finished with text input." << endl;
cout << "Enter a line of text: ";
getline( cin, str );
setCharCountArrayToZero( );
while( str != "DONE" ) //continues to get string until "DONE" is entered
{
for( unsigned int i = 0; i < str.length(); i++ ) //checks the entered string and deposits the number of occurance of a letter to the corresponding index in charCountArray (e.g. 'a' and 'A' fo to index 0)
{
int ch = str[i];
if( ch >= 'a' && ch <= 'z' )
{
// Increment the charCountArray for the letter.
charCountArray[ch-'a']++;
} else if( ch >= 'A' && ch <= 'Z' )
{
charCountArray[ch-'A']++;
}
}
cout << "Enter a line of text: ";
getline( cin, str );
}
int length = getStringLength( );
freqCalculator(length );
int maxValueIndex = findLargestValueIndex( );
for( int p = 0; p < 26; p++ )
{
cout << charFreqArray[p] << endl;
}
cout << endl << "A total of " << length << " letters of the alphabet were processed." << endl << endl;
printFrequency(charFreqArray[maxValueIndex]);
cout << endl << "The most common letter is "
<< "'" << (char) ( maxValueIndex + 'a' ) << "'"
<< " with a frequency of " << charFreqArray[maxValueIndex] << "%." << endl;
return 0;
}
void setCharCountArrayToZero( ) //initializes all elements of the countArray to 0
{
for( int i = 0; i < 26; i++ )
charCountArray[i] = 0;
}
int getStringLength( ) //calculates and returns the total number of alphabets entered
{
int result = 0;
for( int i = 0; i < 26; i++ )
result += charCountArray[i];
return result;
}
int findLargestValueIndex( ) //finds the index # for the most frequent letter
{
int maxValue = charCountArray[0];
int result = 0;
for( int i = 0; i < 26; i++ )
{
if( charCountArray[i] >= maxValue )
{
maxValue = charCountArray[i];
result = i;
}
}
return result;
}
void freqCalculator(int length)
{
for( int i = 0; i < 26; i++ ) //calculates the frequency percentage
charFreqArray[i] = charCountArray[i]/(double) length * 100;
}
void printFrequency(double maxValue)
{
for( char i = 'a'; i <= 'z'; i++ )
{
cout << i << " ";
}
cout << '%' << endl << endl;
for ( int i = 0; i < 10; i++ )
{
for( char lett = 0; lett < 26; lett++ )
{
if( charFreqArray[lett] > maxValue * i / 10 )
cout << "* ";
else
cout << " ";
}
cout << i+1;
cout << endl;
}
}
|