Reputation: 11
first time on Stack here, I hope to learn from you guys! So my code involve the user reading a passage from a text-file and adding the word into a vector. That vector would be pass into a word count function and print out how many word are repeating. for example: count per word: age = 2 , belief = 1, best =1, it = 10 however i'm trying to come up with a function that loop to the same vector and print out the word that are repeated more than two time. In this case the word "it" is repeated more than two time.
map<string, int> get_word_count(const vector<string>& words) {
map<string, int> word_count{};
for (string word : words) {
auto search = word_count.find(word);
if (search == word_count.end()) {
word_count[word] = 1; // not found - add word with count of 1
}
else {
word_count[word] += 1; // found - increment count for word
}
}
return word_count;
}
this is my snipet of code that check the many word that are repeated from the vector. However im struggle to figure out how to add a condition to check if the word are repeated twice or more than two time. I try to add a condition if word_count > 2, then print out the repeated word of twice. However it did not work. I hope to hear from you guys hint, thank.
Upvotes: 0
Views: 107
Reputation: 91
first of all I really suggest you to explore documentation about C++ before coding, your code is actually rewritable in this way
map<string, int> get_word_count(const vector<string>& words) {
map<string, int> word_count{};
for (string& word : words) {
word_count[word] += 1;
}
return word_count;
}
This works because map::operator[] (like unordered_map::operator[]) doesn't work like map::at does (which throws a std::out_of_range exception if the key is not in the map). The difference is that operator[] returns a reference to the Value at the given key and if the key is not already in the map, it is inserted and default-initialized (in your case a int is value-initialized to 0). Operator[] on cppreference
In order to add the "twice or more than twice" part you can modify your code by adding the condition in the for loop.
map<string, int> get_word_count(const vector<string>& words) {
map<string, int> word_count{};
for (string& word : words) {
auto& map_ref = word_count[word];
map_ref += 1;
if(map_ref == 2){
// Here goes your code
}
}
return word_count;
}
If you're interested in how many times a word is repeated you shall scan again the map with a loop.
Upvotes: -1
Reputation: 25593
No need to check as a std::map
automatically check if the entry exists or not. If not, it creates a new one, if yes, the value is handled correctly.
Simply loop over the std::map
which holds the words vs. counts and use a condition as needed. See full example.
int main()
{
std::vector< std::string > words{ "belief","best","it","it","it" };
std::map< std::string, int > counts;
for ( const auto& s: words )
{
counts[s]++;
}
for ( const auto& p: counts )
{
if ( p.second > 2 ) { std::cout << p.first << " repeats " << p.second << std::endl; }
}
}
Hint:
If you write auto x: y
you get a copy of each element of y which is typically not what you want. If you write const auto& x: y
you get a const reference to the element of your container, which is in your case much faster/efficient, as there is no need to create a copy. The compiler is maybe able to "see" that the copy is not needed and optimize it out, but it is more clear to the reader of the source code, what is intended!
Upvotes: 2