Accelerated C++ exercise code review
From: Martin (martin_at_nospam.com)
Date: 10/29/04
- Next message: Jerry Coffin: "Re: C++ and C# and Java"
- Previous message: Alwyn: "Re: C++ and C# and Java"
- Next in thread: B. v Ingen Schenau: "Re: Accelerated C++ exercise code review"
- Reply: B. v Ingen Schenau: "Re: Accelerated C++ exercise code review"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 29 Oct 2004 22:06:20 +0800
I've done an exercise in Accelerated C++ (page 138, Ex 7-1 for those who
have it). It is a standard word frequency program, but the exercise is to
modify it so that the output is sorted by the occurence count, rather than
the words. The original program uses a map<string, int> to store the words
and frequencies. So the job of the exercise is to sort based on the value of
the pair rather than the key. My solution is shown below. It works AFAIK but
I would like to know if it is well-written stylistically and how it could be
improved or simplified. Any comments gratefully received!
My solution creates a vector of map iterators, which are then sorted based
on a custom compare function. The original map is kept untouched. Here is
the code in full:
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <cassert>
using namespace std;
typedef map<string, int>::const_iterator Map_iter;
// compares the int value of a pair<string, int>
bool compare(const Map_iter& a, const Map_iter& b)
{
return a->second < b->second;
}
int main()
{
string s;
map<string, int> counters; // store each word and an associated counter
// read each word into the map
while (cin >> s)
++counters[s];
// create a vector of counter.size elements
vector<Map_iter> vec(counters.size());
assert(vec.size() == counters.size());
// get an iterator to the start of the map
Map_iter map_it = counters.begin();
// copy the map iterators into the vector
for (vector<Map_iter>::iterator it = vec.begin(); it != vec.end(); ++it)
*it = map_it++;
sort(vec.begin(), vec.end(), compare);
// output the map indirectly via the vector
for (vector<Map_iter>::const_iterator it = vec.begin(); it != vec.end();
++it)
cout << (*it)->first
<< setw(8)
<< (*it)->second << endl;
cout << endl << vec.size() << " unique words" << endl;
return 0;
}
The bit I am unsure about is the line
*it = map_it++;
Is it ok to manipulate iterators like this?
Thanks,
Martin
- Next message: Jerry Coffin: "Re: C++ and C# and Java"
- Previous message: Alwyn: "Re: C++ and C# and Java"
- Next in thread: B. v Ingen Schenau: "Re: Accelerated C++ exercise code review"
- Reply: B. v Ingen Schenau: "Re: Accelerated C++ exercise code review"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]