Solved

Count frequency of words in a file

Posted on 2012-04-08
8
235 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
  • 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
 
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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 32

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 32

Accepted Solution

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

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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

708 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now