Solved

Count frequency of words in a file

Posted on 2012-04-08
8
243 Views
Last Modified: 2012-06-22
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
0
Comment
Question by:Vlearns
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
8 Comments
 

Author Comment

by:Vlearns
ID: 37822517
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 }
0
 
LVL 86

Expert Comment

by:jkr
ID: 37823868
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

0
 

Author Comment

by:Vlearns
ID: 37824485
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?
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 37824569
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

0
 

Author Comment

by:Vlearns
ID: 37824592
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!
0
 
LVL 86

Assisted Solution

by:jkr
jkr earned 300 total points
ID: 37824713
We, you are right, they are not sorted by their cont at the moment, but that can easiy be done:

  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 results:
multimap<int,string> out; // using the count as a key wil cause the output 
                                          // to be sorted by that value

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

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

  out.insert(multimap<int,string>::value_type(ci->second,ci->first));
}

multimap<int,string>::const_iterator ci2 = out.begin();                                 
  
for (; ci2 != out.end(); ++ci2) {

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

Open in new window

0
 
LVL 34

Expert Comment

by:sarabande
ID: 37827111
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
0
 
LVL 34

Accepted Solution

by:
sarabande earned 200 total points
ID: 37827114
correction:

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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question