Easy way to get frequency of letters

Hey,
Suppose that I was to write a function to get the frequency of a letter in a string. Is there an easier way to do they other then having a monster of a switch statement. OK, for example I have an array maybe it just has 3 words. HI, hello, potato.
How can I determine the frequency? As of now the idea is to write a function that takes a word from the array. The function will then go through the word and then if it is a increment the count of a but this goes for upper case to like A. Then the same count will be incremented. This is what results in a really long switch statement. And if this function is int how can I return each of the letters counters? There has to be an easier way to do this. This is what I was playing around with I haven't compiled it yet or anything if you see an easier way please let me know this switch statement tells me there has to be a better way. I just can't see it as of now.
Thanks,
Jordan






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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//A function to determine frequency of letters
int Frequency(string str1)
{	
	// letter counts
	int aFreq, bFreq, cFreq, dFreq, eFreq, fFreq,
	gFreq, hFreq, iFreq, jFreq, kFreq, 
	lFreq, mFreq, nFreq, oFreq, pFreq,
	qFreq, rFreq, sFreq, tFreq, uFreq, 
	vFreq, wFreq, xFreq, yFreq, zFreq;
	
	// Var for letter from string
	char letter = ' ';
	
	//Loop to get letter
	for(int i = 0; i < str1.size(); i++)
	{	
		letter = str1.at(i);
	}
// Switch to count the letters
	switch (letter)
{
	case 'A': aFreq ++;
	break;
	case 'a': aFreq++;
	break;
	case 'B': bFreq ++;
	break;
	case 'b': bFreq++;
	break;
	case 'C': cFreq ++;
	break;
	case 'c': cFreq++;
	break;
	case 'D': dFreq ++;
	break;
	case 'd': dFreq++;
	break;
	case 'E': eFreq ++;
	break;
	case 'e': eFreq++;
	break;
	case 'F': fFreq ++;
	break;
	case 'f': fFreq++;
	break;
	case 'G': gFreq ++;
	break;
	case 'g': gFreq++;
	break;
	case 'H': hFreq ++;
	break;
	case 'h': hFreq++;
	break;
	case 'I': iFreq ++;
	break;
	case 'i': iFreq++;
	break;
	case 'J': jFreq ++;
	break;
	case 'j': jFreq++;
	break;
	case 'K': kFreq ++;
	break;
	case 'k': kFreq++;
	break;
	case 'L': lFreq ++;
	break;
	case 'l': lFreq++;
	break;
	case 'M': mFreq ++;
	break;
	case 'm': mFreq++;
	break;
	case 'N': nFreq ++;
	break;
	case 'n': nFreq++;
	break;
	case 'O': oFreq ++;
	break;
	case 'o': oFreq++;
	break;
	case 'P': pFreq ++;
	break;
	case 'p': pFreq++;
	break;
	case 'Q': qFreq++;
	break;
	case 'q': qFreq ++;
	break;
	case 'R': rFreq++;
	break;
	case 'r': rFreq ++;
	break;
	case 'S': sFreq++;
	break;
	case 's': tFreq ++;
	break;
	case 'T': uFreq++;
	break;
	case 't': tFreq ++;
	break;
	case 'U': uFreq++;
	break;
	case 'u': uFreq ++;
	break;
	case 'V': vFreq++;
	break;
	case 'v': vFreq ++;
	break;
	case 'W': wFreq++;
	break;
	case 'w': aFreq ++;
	break;
	case 'X': aFreq++;
	break;
	case 'x': aFreq ++;
	break;
	case 'Y': aFreq++;
	break;
	case 'y': aFreq++;
	break;
	case 'Z': aFreq ++; 
	break;
	case 'z': aFreq++;
	break;
	default: letter ==' ';
     }
	
}

What about using arrays or would I still have to have this matching process?
Arrays are fine. You can convert a letter to an index into the array using some subtraction.

I suggest you #include <cctype> so that you can check to see whether a character is a letter or not:

if (isalpha( str1.at(i) ))

Convert all your letters to uppercase:

char c = toupper( str1.at(i) );

Convert uppercase letters to an index into your array, such that 'A' --> 0, 'B' --> 1, etc:

int index = c - 'A';

You do need to be careful around line 18. You loop through your input, and only after you look at each letter do you attempt to count frequencies. (Meaning you only count the last letter's frequency, which is one -- there is only one last letter.) You should be updating the frequency inside your loop.

Hope this helps.
Last edited on
Or, if you're feeling frisky, you could use a std::map storing letter counts that are indexed by letter. But, that's probably overkill.
Duoas (6694)

I think I get what you are saying but I have run into problems with the actual code for this. I have an issue with the the array if I declare it as char. Here is what I have written .


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
#include <iostream>
#include<iomanip>
#include <string>
using namespace std;

//Function to remove garbage off word
void onlyAlpha(string& str1)
{	
	string newStr1 ="";
	newStr1.reserve(str1.size()); 

	for(string::size_type i = 0; i < str1.size(); i++)
	{	
		if ( isalpha( str1[i] ) ) 
		newStr1.push_back( str1[i] );
		
	}
	str1= newStr1;
}

// to help frequency process
 void freqhelp(string& str1)
 {
	 for(string::size_type i =0; i <str1.size(); i++)
	 {
		 toupper(str1[i]);  // This is obviously a probelm this whole function I'm not sure how to write this.
                 str1[i]-65;                     
	 }
}

 //A function to determine frequency of letters
void  fillFrequency(string str1, string freqcount[], const int alphabet)
{	
	for(string::size_type i =0; i <str1.size(); i++)
	{
		freqcount[i] = freqhelp(str1[i]);  This part I just want to give str1 to the function have it convert to upper subtract 65 (ascii) and then increment the freq at that position and store it in the array freqcount 
	}

	
}


//Function to fill new array with new words.
void funfun(string str1[], const int isize, int& countWord)
{	

	for(string::size_type i = 0; i <  isize; i++)
	{
		onlyAlpha(str1[i]);
		countWord++;
	}		
		
}


void main()
{
	const int isize = 3;	
	string str1[]={"!!HELLO","WHAT###", "%%NOW"};
	string test= "!!dude";
	const int size = 100;
	string wordsminus[size];
	int wordCount = 0;
	const int alphabet = 26;
	string freqcount[alphabet];
	funfun(str1,isize,wordCount);
	onlyAlpha(test);
	
	
	for(int j = 0; j < isize; j++)
	{
		cout << str1[j]<< "\t";
	}
	cout << wordCount;
	system("pause");
}	



Hopefully someone knows what I'm trying to explain. I just want to fill an array with the size 1-26 for the alphabet then I just want to store the freq of a given letter at position i from the word str1.
Thanks
I get this error.
1>c:\users\jordan\documents\visual studio 2010\projects\ifelse\ifelse\beauproject.cpp(36): error C2664: 'freqHelp' : cannot convert parameter 1 from 'char' to 'std::string &'


I don;t know why I changed it so it shouldn;t (at least I think )


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
// to help frequency process
 void freqHelp(string& str1)
 {
	 for(string::size_type i =0; i < str1.size(); i++)
	 {
		 toupper(str1[i]);
		 str1[i-65] ++;
	 }
}

 //A function to determine frequency of letters
void  fillFrequency(string str1, string freqcount[], const int alphabet)
{	
	for(string::size_type i =0; i <str1.size(); i++)
	{
		freqcount[i] = freqHelp(str1[i]);
	}

	
}


//Function to fill new array with new words.
void funfun(string str1[], const int isize, int& countWord)
{	

	for(string::size_type i = 0; i <  isize; i++)
	{
		onlyAlpha(str1[i]);
		countWord++;
	}		
		



}


void main()
{
	const int isize = 3;	
	string str1[]={"!!HELLO","WHAT###", "%%NOW"};
	string test= "!!dude";
	const int size = 100;
	string wordsminus[size];
	int wordCount = 0;
	const int alphabet = 26;
	string freqcount[alphabet];
	funfun(str1,isize,wordCount);
	onlyAlpha(test);
	
	
	for(int j = 0; j < isize; j++)
	{
		cout << str1[j]<< "\t";
	}
	cout << wordCount;
	system("pause");
}	
I appreciate that you got someone to try to help you, but now you are stuck with too much stuff to think about at once. In particular, you have too many functions. Try to get rid of freqHelp() at the least.

I liked your original code better.

Your freqcount[] array should be an array of what? (Currently it is an array of strings. Remember that you are counting things with it.)

Something important that you are struggling with right now is the idea that everything has a type -- that is, everything is a certain kind of thing. A string is a thing that is a list of characters. A character is a number that represents some piece of text that humans read, like the letter 'A' or a question mark '?'. An integer is a negative or non-negative whole number, including zero.

A variable is the corporeal manifestation of a type:

1
2
3
4
string name           = "Jacob";
int    days_in_a_week = 7;
char   middle_initial = 'D';
float  pi             = 3.1415926;

You cannot mix things of different types. name = pi; doesn't make sense, because a number is not a string.

After all that, consider what is meant by onlyAlpha(str1[i]) when onlyAlpha()'s argument is a reference to a string. (Remember, what is the type of str1[i]?)


Seriously, though, you do need to work on figuring this out for yourself. You are actually doing pretty well, but all the people trying to help you are doing you a disservice. If I were you, I would start over with the code you started with. Get rid of the great big switch statement and use the operations I told you about.

In order to use them, you will have to read up on how to use functions. Try the tutorial here, it will help you considerably.
http://www.cplusplus.com/doc/tutorial/

Good luck!
Last edited on
OK I will just give the part that is the problem. Why do I keep getting the error? I see what your saying about types but I cant see it in this particular problem.
1
2
3
4
5
for(string::size_type i = 0; i <str1.size(); i++)
	{
		freqcount[i] = freqHelp(str1[i]);   // This line here str1[i]
	}
}

So freqcount I changed to int. freqHelp is void so it doesn't matter what it takes as long As I have it in the function heading. So I should be OK but I don't about my loop how it is string::size_type. I think it would be OK because it would just increment the position at i in the freqcount array?
Thats all I got guys:)
thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// to help frequency process
 void freqHelp(string& str1)
 {
	 for(string::size_type i =0; i < str1.size(); i++)
	 {
		 toupper(str1[i]);
		 str1[i-65] ++;
	 }
}

 //A function to determine frequency of letters
void  fillFrequency(string str1, int freqcount[], const int alphabet)
{	
	for(string::size_type i = 0; i <str1.size(); i++)
	{
		freqcount[i] = freqHelp(str1[i]);   // This line here str1[i]
	}
}

I understand what your saying about types.
What does freqHelp return that you're trying to assign to freqcount[i]?

What type is str1[i]? What type does freqHelp take as a parameter?
Topic archived. No new replies allowed.