• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2100
  • Last Modified:

C++ question in indicating the number of occurrences of letters

Hi,
    I can't seem to figure out how I can write a program that reads several lines of text from the keyboard and prints a table indicating the number of occurrences of each letter of the alphabet in the text.  For example, the phrase

"I went to the store"

contains no "a's," no "b's," ....two "e's"..etc (alphabetically)

The following program is what I have:

#include <iostream.h>
#include <string.h>
 
void input();
void new_line();
const int size = 30;
 
int main()
{
      char string[size];
      char ans;
       
      do
      {
      cout<<"Please enter a line.\n";
      cin.getline(string, 30);
      cout<< string << endl;
      cout<< strlen(string) << endl;         
 
      cout<<"Yes/No\n";
      cin>> ans;
      new_line();
      }
      while((ans != 'n') && (ans != 'N'));
       return 0;
}

void new_line()
{
      char symbol;
      do
      {
            cin.get(symbol);
      }while(symbol != '\n');
}


Any types of help is appreciated

regards,
  shwn
0
Shwn
Asked:
Shwn
1 Solution
 
kgreddyCommented:
You please post the code if you have already tried the program.
I can tell you where you went wrong.

If you are new to programming altogether, refer to a C++
book and see what you need to do to accept text from the
key board.
After you accept the text from key board, you have to scan through
the text and keep a count of alphabets.

0
 
ShwnAuthor Commented:
Edited text of question.
0
 
ResonanceCommented:
First, a note on what you have so far.  Unless you're really trying to optimize for speed and memory, you don't ever want to use character arrays.  You risk overflow errors, off-by-one counts of data, forgotten terminators.  To input a single line of character data, I heartily recommend the following:

string inputstr;
getline(cin,inputstr);

The string can be treated for the most part like a character array, but has automatic bounds checking and termination and other nifty features.  You can also use inputstr.size() to get the size once you have handled the input.

The simplest, if perhaps not the most code-efficient way to handle the histogram is to start with 26 variables, one for each letter, initialize them to zero, and then run two for loops on the text from 0 to maxsize-1, first using tolower() on each item, and then using switch(inputstr[ctr]), case "a": a++; break; case "b": b++; break; and so on down to z.

So you'll have code that looks like this:

int main(void)
{
string inputstr;
getline(cin,inputstr);

hist(inputstr);

return 0;
}

void hist(string istr)
{
short int a=0;
short int b=0;
....
short int z=0;

short int ctr;

for(ctr=0;ctr<istr.size();ctr++)
{
istr[ctr]=tolower(istr[ctr]);
}

for(ctr=0;ctr<istr.size();ctr++)
{
switch(istr[ctr])
{
case "a":
  a++;
  break;
case "b":
  b++;
  break;
....
 case "z":
  z++;
  break;

 default:
  cerr << "This shouldn't happen." << endl;
  exit(1);
}
}

cout << "a count: " << a << endl;
cout << "b count: " << b << endl;
....

return;
}

And there you have it.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
ShwnAuthor Commented:
Resonance,
    I like the idea of using switch and cases in your proposed program.  I've tried to incorporate your program into mine but it doesn't seem to assimilate correspondingly.  How would you go about writing the declaration and defining the class for the class of your program? Thanks in advance

Regards,
  Shwn
0
 
jasonclarkeCommented:
I think the use of seprate variables for this type of things is a bit unpleasant.

There is a data structure which is designed specifically for this type of application - called a map or associative array.  It allows you to associate a key (in your case the character) with a value (the count of characters).

Here is a version of the code that does something like what you want:

#include <iostream>
#include <map>
#include <string>

using namespace std;

// Need the pragma for Visual C++ :-(
#pragma warning(disable:4786)

void main()
{
    string line;

    map<char,int>  characterMap;

    cout << "Type some text, type END to stop." << endl;
    getline(cin,line);
    while (line != "END")
    {
        for (int i=0; i<line.length(); i++)
        {
            char thischar = line[i];
            if (tolower(thischar) >= 'a' && tolower(thischar) <= 'z')
            {
                if (characterMap.find(thischar) == characterMap.end())
                {
                                        characterMap[thischar] = 0;
                }
                ++characterMap[thischar];
            }
        }
        getline(cin,line);
    }

    map<char,int>::iterator i = characterMap.begin();
    while (i != characterMap.end())
    {
        cout << i->first << " = " << i->second << endl;
        ++i;
    }
}
0
 
ResonanceCommented:
I'd like to start by saying that Jason's solution is much more elegant than mine, and you should probably go with it.

However I'm a little confused about what you mean by "writing the definition and defining the class", since I wrote no functions, and created no new classes.
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now