Skip to content

Commit 7db5ab8

Browse files
committed
Consolidate freqency of baby names given that names can have synynyms
1 parent 2cacb28 commit 7db5ab8

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

17-Hard/7-Baby-Names.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
Baby Names:
3+
Each year, the government releases a list of the 10,000 most common baby names
4+
and their frequencies (the number of babies with that name). The only problem with this is that
5+
some names have multiple spellings. For example, "John" and "Jon" are essentially the same name
6+
but would be listed separately in the list. Given two lists, one of names/frequencies and the other
7+
of pairs of equivalent names, write an algorithm to print a new list of the true frequency of each
8+
name. Note that if John and Jon are synonyms, and Jon and Johnny are synonyms, then John and
9+
Johnny are synonyms. (It is both transitive and symmetric.) In the final list, any name can be used
10+
as the "real" name.
11+
EXAMPLE
12+
Input:
13+
Names: John (15), Jon (12), Chris (13), Kris (4), Christopher (19)
14+
Synonyms: (Jon, John), (John, Johnny), (Chris, Kris), (Chris, Christopher)
15+
Output: John (27), Kris (36)
16+
*/
17+
18+
// g++ 7-Baby-Names.cpp --std=c++14
19+
20+
#include <iostream>
21+
#include <string>
22+
#include <unordered_map>
23+
#include <set>
24+
#include <stack>
25+
26+
using std::cout;
27+
using std::endl;
28+
using std::string;
29+
using std::unordered_map;
30+
using std::set;
31+
using std::stack;
32+
33+
struct Node {
34+
string name;
35+
int freq;
36+
set<string> neighbour;
37+
38+
Node( string name_, int freq_ ) : name( name_ ), freq( freq_ ) {}
39+
};
40+
41+
class Graph {
42+
unordered_map<string, Node *> nodes;
43+
44+
void addNodes( const unordered_map<string, int> nameToFreqMap ) {
45+
for( auto itr = nameToFreqMap.begin(); itr != nameToFreqMap.end(); itr++ ) {
46+
nodes.insert( std::make_pair( (*itr).first,
47+
new Node( (*itr).first, (*itr).second ) ) );
48+
}
49+
}
50+
51+
void addEdges( const unordered_map<string, string> synonymMap ) {
52+
for( auto it = synonymMap.begin(); it != synonymMap.end(); it++ ) {
53+
string a = (*it).first;
54+
string b = (*it).second;
55+
// add b to a neighbour
56+
nodes[a]->neighbour.insert( b );
57+
// add a to b neighbour
58+
nodes[b]->neighbour.insert( a );
59+
}
60+
}
61+
62+
void dfs( string node, unordered_map< string, bool> &visited, int &sum ) {
63+
stack< string > s;
64+
s.push( node );
65+
visited[ node ] = true;
66+
sum += nodes[ node ]->freq;
67+
while( !s.empty() ) {
68+
string tmp = s.top();
69+
s.pop();
70+
for( auto n : nodes[ tmp ]->neighbour ) {
71+
// if not visited put in stack
72+
if( visited.find( n ) == visited.end() ) {
73+
visited[ n ] = true;
74+
sum += nodes[ n ]->freq;
75+
s.push( n );
76+
}
77+
}
78+
}
79+
}
80+
81+
public:
82+
void createGraph( const unordered_map<string, int> nameToFreqMap,
83+
const unordered_map<string, string> synonymMap ) {
84+
this->addNodes( nameToFreqMap );
85+
this->addEdges( synonymMap );
86+
}
87+
88+
auto getCount() {
89+
unordered_map< string, bool> visited;
90+
unordered_map< string, int> nameToFreq;
91+
for( auto it = nodes.begin(); it != nodes.end(); it++ ) {
92+
if( visited.find( (*it).first ) == visited.end() ) {
93+
// if the node has not been visited get the sum of all the nodes in that
94+
// connected component
95+
int sum = 0;
96+
this->dfs( (*it).first, visited, sum );
97+
nameToFreq[ (*it).first ] = sum;
98+
}
99+
}
100+
return nameToFreq;
101+
}
102+
103+
};
104+
105+
int main() {
106+
unordered_map<string, int> nameToFreqMap = { {"john", 10}, {"jon", 3}, {"davis", 2},
107+
{"kari", 3}, {"johnny", 11}, { "carlton", 8},
108+
{"carleton", 2}, {"jonathan", 9}, {"carrie", 5} };
109+
unordered_map<string, string> synonymMap = { {"jonathan", "john"}, {"jon","johnny"},
110+
{"johnny", "john"}, {"kari","carrie"},
111+
{"carleton", "carlton"} };
112+
113+
Graph g;
114+
g.createGraph( nameToFreqMap, synonymMap );
115+
116+
unordered_map< string, int> nameToFreq = g.getCount();
117+
for( auto it = nameToFreq.begin(); it != nameToFreq.end(); ++it ) {
118+
cout<< "Name: " << (*it).first << " Count: " << (*it).second << endl;
119+
}
120+
return 0;
121+
}

0 commit comments

Comments
 (0)