Need some help.

Hi guys,

This is a problem that I'm unsure how to solve.

Essentially, the task is to have the user enter in a sentence that ends with a period and then count how many times each letter is repeated up to that period. The program then outputs each letter in the sentence along with the amount of times it is repeated in decreasing order.

For example, if the user enters: "hello ." the output should be something similar to this:

l: 2
h: 1
e: 1
o: 1

-----------------------------------------------------------------------------

This is my plan so far:

1. Get input from user.

2. Get rid of any unnecessary spaces in input.

3. Store each letter into a vector v and keep storing letters up to the period.

4. Make two parallel vectors: one for letters and one for storing how many times
a particular letter is repeated.

5. Search vector v for repeats. If letter repeats, store it into vector "letters".

6. At the same time, keep track of how many times each letter is repeated and add '1' to my counting vector, which is parallel to my letters vector.

7. Sort the vector that does the counting from highest to lowest and sort the "letters" vector according to the same positions of the counting vector.

8. Output both vectors.

--------------------------------------------------------------------------

Does this seem like the way I should go about it? Or is there some way that is more easier/efficient? Sorry if this is long. Keep in mind that I have only been programming for 2 months so I do not have a vast of knowledge yet.

If you have any tips, let me know. Thank you. Here is my code up to now...


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

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

string getInput(); //string input by user
void loadVector(vector<char>& v,string input);

int main()
{
    vector<char> v;
    string input = getInput();
    loadVector(v, input);
    
    vector<char> letters;
    vector<int> count;
    
    for (int i = 0; i < v.size(); i++)
    {
        cout << v[i];
    }
    
    return 0;
}

string getInput()
{
    int period = 0;
    string input;

    do
    {
        cout << "Enter a sentence; Enter a period to end sentence: ";
        getline(cin, input);
        
        for (int i = 0; i < input.size(); i++)
        {
            if (input[i] == '.')
                period += 1;
        }
        
    } while (input.size() == 0 || period == 0);
    
    return input;
}

void loadVector(vector<char> &v, string input)
{
    // loads vector, takes out spaces
    // stops loading vector when input[i] == '.'
    
    int i = 0;
    
    do
    {
        if (input[i] != ' ')
            v.push_back(input[i]);
        i++;
    } while (input[i] != '.');
}


Last edited on
closed account (D80DSL3A)
That's cool. Is it working?

I thought I'd share a wacky solution I just whipped up.
Wouldn't it be nice if we could store both the character and the count in a single variable?
Actually, use of std::pair<char,int> for this would be just right.

I used a vector of ints. I store the ascii value of any newly found character, then add 1,000 for each time the character is found.

Using std::vector<int> chCount; as the container.
Will wind up with chCount.size() unique letters. For each letter
letter = (char)(chCount[i]%1000) and count = chCount[i]/1000;
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 <iostream>
#include <vector>
#include <fstream>

using namespace std;// bad habit here.

int main()
{
    unsigned i = 0;// for looping
    vector<int> chCount;
    ifstream fin("test.txt");
    if( !fin ) return 1;

    char chIn;// read letters until a . is found
    while( fin >> chIn && chIn != '.' )
    {
        if( chIn == ' ' ) continue;// just a space. Next!

        // go through list of characters found so far.
        for( i = 0; i < chCount.size() && chCount[i]%1000 != (int)chIn; ++i );

        if( i == chCount.size() )// chIn was not found
            chCount.push_back( (int)chIn + 1000 );// add to list of letters
        else// increase count
            chCount[i] += 1000;
    }

    // display letters found and the counts
    cout << " ch  count \n";
    for( i = 0; i < chCount.size(); ++i )
        cout << (char)(chCount[i]%1000) << "  " << chCount[i]/1000 << endl;

    return 0;
}

It works, but it is a bit wacky.

With the following in test.txt:
mary had a little lamb.

The program produces:

 ch  count
m  2
a  4
r  1
y  1
h  1
d  1
l  3
i  1
t  2
e  1
b  1
Last edited on
Hi fun2code,

Thanks for your input. Actually, the assignment says explicitly to get input from the console and not from a file. I do however have a few days to think more about this problem.

A question though,

When you are counting repeated characters, why do you do this:
chCount[i] += 1000;

instead of this:
chCount[i] += 1;

is there a specific reason for this?

I will update my code soon after i think on it for a little bit.

Thanks again




Its so that he can store both the character and the count in a single variable. Because a character is returned as a char, with a maximum value of 255, any number larger than that would have the same effect. Every time it is found, he is adding 1000 more to the count. At the end he is getting the modulus of 1000 (the 0-999, or the characters themselves) and casting them to a char to get the value, and then he divides it by 1000 to get the count. If you don't want files, simply get rid of he calls for fin in lieu of calls for cin.

Here is how I would do it - using a map:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <map>
#include <iostream>
#include <cctype>

int main() {
    std::map<char, unsigned int> letterCount;

    char ch;
    while (std::cin >> ch && ch != '.') {
        if (std::isspace(ch)) continue;
        ++letterCount[ch];
    }

    std::cout << "ch\tcount\n";
    for (const auto& it : letterCount)
        std::cout << it.first << '\t' << it.second << '\n';

    return 0;
}
mary had a little lamb.
ch	count
a	4
b	1
d	1
e	1
h	1
i	1
l	3
m	2
r	1
t	2
y	1

http://coliru.stacked-crooked.com/a/1681f4f91a863692

EDIT:
Typos.
Last edited on
Topic archived. No new replies allowed.