Link to home
Start Free TrialLog in
Avatar of Vlearns
Vlearns

asked on

Count frequency of words in a file

Hi

I have a file input.txt such as

amy
mish
lol
amy
vl
amy
mish

Can you help me write a simple c++ program that prints out

amy 3
mish 2
lol 1
vl 1
Avatar of Vlearns
Vlearns

ASKER

here is the starter code

  1 #include <fstream>
  2 #include <string>
  3 #include <iostream>
  4 #include <sstream>
  5 #include <map>
  6 #include <vector>
  7 using namespace std;
  8
  9 int main() {
 10
 11 ifstream file("log");
 12 string   line;
 13 vector<int> pages;
 14 map<string,vector<int> > map1;
 15
 16 while(getline(file, line))
 17 {
 18     stringstream   linestream(line);
 19     string         data;
 20     string         val1;
 21     int            val2;
 22
 23    linestream >> val1
 24
 25    
 28    cout << " i am val1 " << val1 << endl;
 29
 30 }
 31 }
Avatar of jkr
A map is already a good approach, yet using a vector<int> as a value to that seems odd to me - you coud just

  map<string,int> wordmap;

  string word;
  // read word

  // ...

  map<string,int>::iterator i = wordmap.find(word);

  // has already an entry?
  if (wordmap.end() != i) {

    // yes, so increase count
    i->second++;

  }  else {

    // new word, insert it
    wordmap.insert(map<string,int>::value_type(word,1)); // initial integer value is '1'
  }

Open in new window

Avatar of Vlearns

ASKER

i think we need a vector to sort the words by their count, right? Your example does not print


amy 3
mish 2
lol 1
vl 1

sorted by their count, since maps cannt be sorted

 1 #include <fstream>
  2 #include <string>
  3 #include <iostream>
  4 #include <sstream>
  5 #include <map>
  6 #include <vector>
  7 using namespace std;
  8
  9 struct data{
 10     string word;
 11     int number;
 12 };  
 13
 14 int main() {
 15
 16 ifstream file("log");
 17 string   line;
 18 data dat1;
 19 vector<data> datavec;
 20
 21 while(getline(file, line))
 22 {  
 23    stringstream   linestream(line);
 24    string val1;
 25    
 26    linestream >> val1;
 27    
 28    iterate through the vector and find the if struct with string val exists, if yes increment the count of the structure,

else add a new element (struct) to the vector?
Wel, I didn't think the printing part was necessary, but that woud be

  map<string,int> wordmap;

  string word;
  // read word

  // ...

  map<string,int>::iterator i = wordmap.find(word);

  // has already an entry?
  if (wordmap.end() != i) {

    // yes, so increase count
    i->second++;

  }  else {

    // new word, insert it
    wordmap.insert(map<string,int>::value_type(word,1)); // initial integer value is '1'
  }

// print resuts:

map<string,int>::const_iterator ci = wordmap.begin();

for (; ci != wordmap.end(); ++ci) {

  cout << ci->first << " " << ci->second << endl;
}
                                            

Open in new window

Avatar of Vlearns

ASKER

Hi jhr,

i do not think your solution will print/sort the strings by their counts
can you help me modify my vector of  structs based solution?

thanks!
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
you don't need a find for counting. simply do

mymap[val1]++;

Open in new window


that statement would set count to 1 in case val1 was a new key or would increment the current count for val1 else.

to sort the results you could use std::map<int, std::vector<std::string> > mysortmap.

mysortmap[iter->second]->push_back(iter->first);

Open in new window


where iter would be iterator of the first map.

finally reverse iteration of mysortmap and inner loop which iterates element vector rev_iter->second would do what you needed.

Sara
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial