how to count each letter in each word

hi guys
im new in c++ and i dont know much

the homework problem asks to count each word from the user input and then count the occurrence of each letter in the sentence

how would i count each occurrence in each word?

so, say, a user inputs the following:


i say hi


the output would be as follows:

3 word(s)
1 a
1 h
2 i
1 s
1 y



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
string input;
	int words = 0;
	unsigned i = 0;
	input = userPrompt(input);

	while (isspace(input.at(i)))
		i++;
	//word count
	{

		for (int i = 0; i < input.length(); i++)
		{
			if (isspace(input.at(i)))
			{
				words++;

				while (isspace(input.at(i++)))
					if (input.at(i) == '\0')
						words--;
			}
		}

		cout << words << " word(s)" << endl;
	}

//need to count each letter in each word 


i also realized that i have to do some kind of sorting so that the letters are alphabetized.
Last edited on
No need for sorting. You can do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>

int main()
{
	std::string input;
	std::getline(std::cin, input); //Get Input
	int l[26]{0}; //Array of 26 for 26 letters

	for (int i = 0; i < input.length(); i++)
	{
		l[toupper(input[i]) - 65] += 1; //Add 1 to Element Holding The Letter
	}

	for (int i = 0; i < 26; i++)
	{
                //EDIT: Adding this if statement so it doesn't show unneeded output:
                if(l[i] > 0)
		std::cout << char(65 + i) << " Showed Up: " << l[i] << '\n'; //Output The Letter And Number Of Times It Appears
	}
}


Input: Ice cream

A Showed Up: 1
C Showed Up: 2
E Showed Up: 2
I Showed Up: 1
M Showed Up: 1
R Showed Up: 1


There are always more ways to do things, but this is a way without much hard coding, so the code is shorter.
Last edited on
@gongong, it gives you the idea.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main(){
	string s="this is a line"; //all lowercase
	int size= s.size();
	int count;
	
	for(int i=0; i<size; i++){
		count=0;
		for(int j=0; j<size; j++){
			if(s[i]==s[j]){
				count++;
			}
		}
		cout << s[i] << " appears " << count<< " times\n"; 
	}
return 0;	
}

output:
t appears 1 times
h appears 1 times
i appears 3 times
s appears 2 times
  appears 3 times
i appears 3 times
s appears 2 times
  appears 3 times
a appears 1 times
  appears 3 times
l appears 1 times
i appears 3 times
n appears 1 times
e appears 1 times

now you have to remove multiple entries, spaces(dots etc.), also think about uppper/lower case letters.
thanks for you guys' help.

one thing, though, what is 65 for?
In the ASCII table, which is the character set used as a "start" in modern work (limited to the English alphabet), the capital letter A has the numeric value of 65 (B is 66, etc).

It's the start of the alphabet.
https://www.learncpp.com/cpp-tutorial/chars/

Every character in a computer has a binary number that represents it. In this case, 'A' is represented by 65.
oh we haven't learned ASCII -- i dont think -- so i guess i'll changed it to 'A'
That works too
C++ basically mandates Latin-1 encoding in the Standard, but it is always better to avoid magic numbers anyway. Use 'A' instead of 65. (A char is an integer type, so you can use it directly.)

Using a short array to hold the letters is a good answer. Zapshe should have suggested better variable names, like histogram (or something similar) for the letter lookup.

His code also has an overflow error: before accessing the array on line 12 he should have verified that both the array and the input is within bounds:

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
	int histogram[ 'Z' - 'A' + 1 ] = { 0 };  // correctly-sized array
	int word_count;
	char last_c = ' ';

	for (char c : input)
	{
		if (std::isalpha( c ))       // no out-of-bounds accesses
		{
			histogram[ std::toupper( c ) - 'A' ] += 1;
		}
		else if (std::isspace( c ) && !std::isspace( last_c ))
		{
			word_count += 1;
		}
		last_c = c;
	}

	if (!std::isspace( last_c ))
	{
		word_count += 1;
	}

And don’t forget to #include <cctype> for those fancy character handling routines.

If I were doing this, I would be inclined to use a std::map <char, std::size_t> for my histogram — all that character arithmetic would be obviated, and there would be no need to check against zero values in the histogram.

Here’s something that is almost guaranteed to get you a fail-for-cheating if you turn it in, but nevertheless demonstrates modern C++ for you:

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
#include <cctype>
#include <iostream>
#include <map>
#include <sstream>
#include <string>

int main()
{
  // These are our letter histogram and word count
  std::map <char, std::size_t> histogram;
  std::size_t                  word_count = 0;

  // Get the input string to break into words
  std::string s;
  std::cout << "s? ";
  getline( std::cin, s );

  // Break the string into words and histogram the letters, case-insensitively
  std::istringstream ss( s );
  while (ss >> s)
  {
    word_count += 1;
    for (char c : s) 
      if (std::isalpha( c ))
        histogram[ std::toupper( c ) ] += 1;
  }

  // Display the word count...
  std::cout << word_count << ((word_count == 1) ? " word\n" : " words\n");
  
  // ...and the letter histogram
  for (auto [c, n] : histogram)
    std::cout << n << " " << c << ((n == 1) ? "\n" : "'s\n");
}

Tada!
s? The quick red fox jumps over the lazy brown dog.
10 words
1 A
1 B
1 C
2 D's
4 E's
1 F
1 G
2 H's
1 I
1 J
1 K
1 L
1 M
1 N
4 O's
1 P
1 Q
3 R's
1 S
2 T's
2 U's
1 V
1 W
1 X
1 Y
1 Z

Hope this helps.
Last edited on
You can't make an omelette without breaking egg's.
Hi duthomhas! Thanks for your reply.
Would you please explain how you used the for loop a little more? ive only used for (int i = 0...i++). are these two the same?
The best way to figure stuff out is to try it!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cctype>
#include <iostream>
#include <string>

int main()
{
  std::string s = "Hello world!";
  
  for (char& c : s)
    c = std::toupper( c );
  std::cout << s << "\n";
  
  for (int n = 0; n < s.size(); n++)
    s[n] = std::tolower( s[n] );
  std::cout << s << "\n";
}
HELLO WORLD!
hello world!

You learn stuff by playing around with it.

Enjoy!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main(){
	char C='a';
	string s="This is a line for test.";
	int dif=int('a')-int('A');
	int count;
	while(C<='z'){
		count=0;
		for(auto j:s){
			if(C==j || C==j+dif)count++;
		}
		if(count>0) cout<< C << " = " <<count <<"\n";
		C++;
	}
		
return 0;
}

output:
a = 1
e = 2
f = 1
h = 1
i = 3
l = 1
n = 1
o = 1
r = 1
s = 3
t = 3


@gongong, read "Range-based for loop" here http://www.cplusplus.com/doc/tutorial/control/
Simply add:

if((toupper(input[i]) - 65) >= 0 && (toupper(input[i]) - 65) <= 25)

or more preferably:

if((toupper(input[i]) - 'A') >= 0 && (toupper(input[i]) - 'A') <= 25)

Ontop of line 12 to make sure the program doesn't go crazy for character input with an ASCII value bigger than the letters.

His code also has an overflow error: before accessing the array on line 12 he should have verified that both the array and the input is within bounds

I personally like to give minimal code so they can simply see the logic.
Last edited on
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
#include <iostream>
#include <string>
#include <cctype>
#include <map>
using namespace std;

using MAP = map<char,int>;


MAP &operator <<( MAP &M, string s )
{
   for ( char c : s ) if ( isalpha( c ) ) M[toupper(c)]++;
   return M;
}    


ostream &operator <<( ostream &strm, const MAP &M )
{
   for ( auto p : M ) strm << p.first << ": " << p.second << '\n';
   return strm;
}


int countWords( const string &s )
{
   int counter = 0;
   char last = ' ';
   for ( char c : s ) 
   { 
      if ( isspace( last ) && !isspace( c ) ) counter++;
      last = c;
   }
   return counter;
}


int main()
{
   string s = "Everything has its beauty, but not everyone sees it.";
   cout << "Wordcount: " << countWords( s ) << '\n';
   MAP freq;
   cout << ( freq << s );
}


Wordcount: 9
A: 2
B: 2
E: 8
G: 1
H: 2
I: 3
N: 3
O: 2
R: 2
S: 4
T: 6
U: 2
V: 2
Y: 3
Last edited on
Topic archived. No new replies allowed.