Counting a vector of strings

I have this exercise: the program receives as an input a .txt file where in the first line there is number of entries, the second line has the minimum number of times a word has to be repeated to be considered and the following lines have all the words. I have to count how many times a word is repeated and then print the word(s).

e.g.
input:

6
2
hey
tomorrow
hey
what
then
then

output:

hey
then

I worked like this: I put the input strings in vector<string> wordList, then in the seek function I count how many times a word is repeated in the vector and insert in the "counting" vector the word and how many times it is repeated. With the sort I sort them so that the number of times is in descending order and in the final loop I print out i < times words.

Result: segmentation fault. I've put some flags around and it seems that the last for loop don't work, as the program runs fine until there.

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

struct wordFreq 
{
	int times;
	string words;
};

void seek (vector<wordFreq> &counting, vector<string> &wList, int dim)
{
	for (int i = 0; i < dim; ++i)
	{
		int count = 0;
		wordFreq word;

		for (int j = 0; j < dim; ++j)
		{
			if (wList[i] == wList[j])
				count++;
		}

		for (int k = 0; k < counting.size(); ++k)
		{
			if (wList[i] != counting[k].words)
			{
				word.times = count;
				word.words = wList[i];
				counting.push_back(word);
				break;
			}
		}
	}
}

bool wayToSort (wordFreq left, wordFreq right)
{
	if (left.times > right.times)
		return true;
	else 
		return false;
}

int main()
{
	int dim;
	int times;
	string word;
	vector<string> wordList;
	vector<wordFreq> counting;

	cin >> dim;
	cin >> times;
	
	for (int i = 0; i < dim; ++i) 
	{
		cin >> word;
		wordList.push_back(word);
	}

	seek (counting, wordList, dim);
	sort (counting.begin(), counting.end(), wayToSort);

	for (int i = 0; i < times; ++i)
	{
		cout << counting[i].words << endl;
	}

}
1
2
3
4
	for (int i = 0; i < times; ++i)
	{
		cout << counting[i].words << endl;
	}


This makes no sense. You are trying to output the following strings:

counting[0]
counting[1]
counting[2]
...
counting[times - 1]

But counting doesn't have that many elements.
Have you considered using a std::map<sting, int> to do the counting automatically for you? Something like:

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

using namespace std;

int main()
{
    std::stringstream sin("6\n2\nhey\ntomorrow\nhey\nwhat\nthen\nthen\n");
    int number_entries;
    int number_occurances_required;

    sin >> number_entries >> number_occurances_required;

    std::string line;
    std::map<std::string, int> freq;

    while(getline(sin, line))
        freq[line]++;


    for(auto& itr : freq)
        if(itr.second >= number_occurances_required)
            std::cout << itr.first << std::endl;

    return(0);
}
@jib

No, because the exercise is technically about vectors, it's from a lesson about them.

@Moschops

I don't get it. Does the seek function have any sense at all? Because that should add the elements to the counting vector.
Last edited on
You seem to be unaware of the fact that std::vectors know their sizes.

So the following should really be using that fact:
1
2
3
4
	for (int i = 0; i < times; ++i)
	{
		cout << counting[i].words << endl;
	}


becoming something like (using C++11 ranged based loops):

1
2
   for(auto& itr : counting)
      cout << itr << endl;


or
1
2
   for(size_t i = 0; i < counting.size(); ++i)
      cout << counting[i].words << endl;


You should also rework the rest of your program to take this into account.
Topic archived. No new replies allowed.