mNames;bool nameExistsAndIncrement(const string& name);
void addNewName(const string& name);
};
Code snippet from NameDB\SecondAttempt\NameDB.h
Here are the new method implementations:
// Reads the names from the file and populates the database.
// The database is a map associating names with their frequency.
NameDB::NameDB(const string& nameFile) throw (invalid_argument)
{
// Open the file and check for errors.
ifstream inFile(nameFile.c_str());
if (!inFile) {
throw invalid_argument("Unable to open file");
}
// Read the names one at a time.
string name;
while (inFile >> name) {
// Look up the name in the database so far.
if (!nameExistsAndIncrement(name)) {
// If the name exists in the database, the
// method incremented it, so we just continue.
// We get here if it didn't exist, in which case
// we add it with a count of 1.
addNewName(name);
}
}
inFile.close();
}
// Returns true if the name exists in the database, false
// otherwise. If it finds it, it increments it.
bool NameDB::nameExistsAndIncrement(const string& name)
{
// Find the name in the map.
auto res = mNames.find(name);
if (res != mNames.end()) {
res->second++;
return true;
}
return false;
}
// Adds a new name to the database
void NameDB::addNewName(const string& name)
{
mNames[name] = 1;
}
// Returns the rank of the name.
// First looks up the name to obtain the number of babies with that name.
// Then iterates through all the names, counting all the names with a higher
// count than the specified name. Returns that count as the rank.
int NameDB::getNameRank(const string& name) const
{
int num = getAbsoluteNumber(name);
// Check if we found the name.
if (num == -1) {
return -1;
}
// Now count all the names in the map that have
// count higher than this one. If no name has a higher count,
// this name is rank number 1. Every name with a higher count
// decreases the rank of this name by 1.
int rank = 1;
for (auto it = mNames.cbegin(); it != mNames.cend(); ++it) {
if (it->second > num) {
rank++;
}
}
return rank;
}
// Returns the count associated with this name.
int NameDB::getAbsoluteNumber(const string& name) const
{
auto res = mNames.find(name);
if (res != mNames.end()) {
return res->second;
}
return -1;
}
Code snippet from NameDB\SecondAttempt\NameDB.cpp
Profile of the Second Attempt
By following the same steps shown earlier, you can obtain the gprof performance data on the new version of the program. The data are quite encouraging:
index %time self children called name
[1] 100.0 0.00 0.21 main [1]
0.02 0.18 1/1 NameDB::NameDB [2]
0.00 0.01 1/1 NameDB::~NameDB [13]
0.00 0.00 3/3 NameDB::getNameRank [28]
[2] 95.2 0.02 0.18 1 NameDB::NameDB [2]
0.02 0.16 500500/500500 NameDB::nameExistsAndIncrement [3]
0.00 0.00 1000/1000 NameDB::addNewName [24]
0.00 0.00 1/1 map::map [87]
If you run this on your machine, the output will be different. It’s even possible that you will not see the data for NameDB methods