Search code examples
c++textcountdownwords

c++ text separate and count words


My task is to input a text, and the output has to be the number of words with 2, 3, 4...n letters, like this:

Hello, whis is my mouse. 2 0 1 2

The symbols ‘ ‘, ‘,’, ‘;’ и ‘.’ counts as word separators. Can you help me with the task? i have this code but can you help me fix the errors?

    #include <iostream>
    #include <string>
    using namespace std;

    int main()
    {
    string text="";
    int size, maxword=0;

    getline(cin, text);
    std::string bb=text;
    size=text.size();
    int b=size;
    int v=size, br=0, t=0, c=0;
    int i=0, a[1000]={0};
    do
    {
        if(text[i]==32 || text[i]==44 || text[i]==59 || text[i]==46)
        {
            a[i]++;
            text.erase (0,i+1);
            size=size-i-1;
            i=0;
        }
        else
        {
            i++;
        }
    }
    while(i<size);
    a[text.size()]++;

    //maxword=broqt bukvi na nai golqmata vsichki bukvi, do predposlednata duma ot teksta
    for(int k=0;k<b;k++)
    {
        if(text[k]==32 || text[k]==44 || text[k]==59 || text[k]==46)
        {
            maxword=k;
            br++;
        }
        if(br==1) break;
    }

    //t=broqt bukvi na poslednata duma ot teksta
    for(int k=b-1;k>=0;k--)
    {
        if(c>0) break;
        else
        {
        if(bb[k]==32 || bb[k]==44 || bb[k]==59 || bb[k]==46)
        {
            for(int m=k+1;m<b;m++)
            {
            t++;
            }
            c++;
        }
        }
    }

    //sravnqva t i maxword, za da vidi broqt bukvi na nai golqmata duma ot teksta
    if(maxword<t) maxword=t;

    for(int y=2;y<maxword+1;y++)
    {
    cout<<a[y]<<endl;
    }
    system("pause");
    return 0;
    }

Solution

  • I would recommend to use std::map here instead of an big array with fixed size (a[1000]) - to simplify the program, make it more secure (no out of bounds check necessary) and to save memory. And the best of it: It can just be indexed like an array with the [] operator

    Your second and third loop is redundant and not necessary - only one loop is needed to calculate the length (and another to output the length at the end of the program).

    Also notice a few things: Instead of using constants for ascii ' ', ';', '.' and ',' you can just use the character constant - it's much easier to understand and improves readability. size_t is a handy unsigned type that can hold the length of any array/string - a size/length can never be signed in normal cases (negative length) - so it's better to use an unsigned type there. And clear variable names like wordCount making the code much easier to reade than just b or a. So I had to change quite a bit in the code, because I couldn't really understand what you were trying to do there.

    Consider this:

    #include <iostream>
    #include <string>
    #include <map>
    
    int main(int argc, const char * argv[]){
      std::string text="";
      size_t pos = 0, count_chars = 0, max_chars = 0;
      std::map<size_t, size_t> wordCount;
      std::getline(std::cin, text);
      do{
        if((text[pos] == ' ') || (text[pos] == ';') || (text[pos] == ',') || (text[pos]=='.')){
          if(count_chars > max_chars) max_chars = count_chars;
          wordCount[count_chars]++;
          count_chars = 0;
        }else{
          count_chars++;
        }
        pos++;
      }while(pos < text.size());
      for(size_t i = 2 ; i < max_chars + 1; i++){
        std::cout << wordCount[i] << std::endl;
      }
      system("pause");
      return 0;
    }
    

    Input:

    Hello, whis is my mouse.
    

    Output:

    2
    0
    1
    2
    

    But be carefull: If your input hasn't the final . after mouse, it would not recognize the last word this way - but that would be easy to fix: You could just do

    if(count_chars>0) wordCount[count_chars]++;
    

    right after the first loop (the do-while one). If you got any questions on this, feel free to ask.