And what was wrong with this code?

3 views
Skip to first unread message

Jozin

unread,
Jul 28, 2011, 12:38:50 PM7/28/11
to coding kata
Dear All,

A short while ago, I have submitted a coding exercise to a
potential employer. The response came back the next
morning and you can guess what it was from the subject
of this post.

I am not totally at loss. I have a couple of guesses, but they
are just that -- guesses. An opinion of somebody with knowledge
would be great, if any of you could spare the time.

The idea of the exercise is simple: I'm given an input file with
names of cars, one per line, possibly repeated and in no
particular order.

The program should output the same names, except with no
repetitions, the number of occurrences listed next to each
car, and in order of decreasing repetitions.

(E.g., "Honda\n Audi\n Honda\n" -> "Honda 2 \n Audi 1\n").

I'd be thankful for any brutally honest feedback.
Thank you all.

////////////////////////////////////////////////////////////////////////////////////

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>

using namespace std;


// helper functions ///////////////////////////////////////

// reads lines from instream
void collect_lines(istream &in, map<string, int> &lines);

// given lines->num_occurs map, reverses mapping
void reorg_by_count(map<string, int> &lines,
multimap<int, string> &bycount);
///////////////////////////////////////////////////////////




int main(int ac, char* av[])
{
istream *in;
map<string, int> *lines = new map<string, int>();
multimap<int, string> *lines_by_count = new multimap<int,
string>();

if (ac < 2)
{
in = &cin;
}
else
{
in = new ifstream(av[1]);
}

if (!in->good()) return 1;

collect_lines(*in, *lines);
reorg_by_count(*lines, *lines_by_count);

if (in != &cin)
{
((ifstream *)in)->close();
delete in;
}

cout << "=====================\n\n";

multimap<int, string>::reverse_iterator it
= lines_by_count->rbegin();

for (; it != lines_by_count->rend(); it++)
{
cout << it->second << " " << it->first << '\n';
}


delete lines;
delete lines_by_count;

return 0;
}


// Read the instream line by line, until EOF.
// Trim initial space. Empty lines skipped
void collect_lines(istream &in, map<string, int> &lines)
{
string tmp;

while (in.good())
{
getline(in, tmp);

int i = 0;

// trim initial space (also skips empty strings)
for (i = 0; i < tmp.length() && !isalnum(tmp[i]); i++);
if (i >= tmp.length()) continue;
tmp = tmp.substr(i);

for (i = 0; i < tmp.length(); i++)
{
if (!isalnum(tmp[i]))
{
tmp[i] = ' ';
}

// thus, HoNdA == Honda
if (i == 0)
{
tmp[i] = toupper(tmp[i]);
}
else
{
tmp[i] = tolower(tmp[i]);
}
}

// and record the counts
if (lines.count(tmp) == 0)
{
lines[tmp] = 0;
}

lines[tmp]++;
}
}


// given lines->num_occurs map, reverses mapping
void reorg_by_count(map<string, int> &lines,
multimap<int, string> &bycount)
{
map<string, int>::iterator it = lines.begin();

for (; it != lines.end(); it++)
{
bycount.insert(pair<int, string>(it->second, it->first));
}
}
Reply all
Reply to author
Forward
0 new messages