Telephonic - Hyderabad - SDE
Given a set of words, find all the anagrams
typedef struct myDataList
{
struct myDataList* next;
struct myDataList* prev;
string data;
myDataList()
{
next = NULL;
prev = NULL;
data = "";
}
}DataList;
typedef struct myList
{
struct myList *next;
DataList *anagramList;
DataList *dataList;
size_t length;
size_t entries;
myList()
{
next = NULL;
anagramList = NULL;
dataList = NULL;
length = 0;
entries = 0;
}
}MainList;typedef stdext::hash_map<string, vector<string>> ANAGRAM;
// Just pushes a few strings for testing purposes
void populateWords(vector<string>& words)
{
words.push_back("act");
words.push_back("tac");
words.push_back("cat");
words.push_back("3214");
words.push_back("2341");
words.push_back("madam");
words.push_back("daamm");
words.push_back("123456");
words.push_back("7123456");
}
// Given a string, sort the chars in the string using counting sort mechanism
// Keeps the count of individual chars in the string in an array where each index represent the count of that char
// Idea behind this is - there are only 0 to 255 ascii values, so each array index can be used to represent a char
// sweep the entire string and increment the appropriate index in the scratch array
// Then traverse the scratch array from left to right and replacing that many char in the original string
void CountingSort(string& sortThis)
{
if(sortThis.size()){
unsigned long count[257];
set<char> distinctChars;
set<char>::const_iterator it, end;
int size = sortThis.size(), index = 0;
memset(count, 0, sizeof(count));
while(index < size){
++count[sortThis[index]];
if(1 == count[sortThis[index]])
distinctChars.insert(sortThis[index]);
++index;
}
index = 0;
it = distinctChars.begin(), end = distinctChars.end();
while(it != end){
while(count[*it]){
sortThis[index++] = *it;
--count[*it];
}
++it;
}
}
}
// Insert the sorted chars sequence into the hash map, if its not present already
// If present, then push it to the vector of strings
// key - sorted string
// value - vector of original strings
void groupAnagrams(const vector<string>& words, ANAGRAM& output)
{
ANAGRAM::iterator hmit;
vector<string>::const_iterator it = words.begin(), end = words.end();
while(it != end){
string sorted = *it;
CountingSort(sorted);
hmit = output.find(sorted);
if(hmit == output.end()){
output[sorted].push_back(*it);
}
else{
hmit->second.push_back(*it);
}
++it;
}
}
// This prints all the anagram words in every line
void printAnagrams(const ANAGRAM& output)
{
ANAGRAM::const_iterator it = output.begin(), end = output.end();
while(it != end){
vector<string>::const_iterator vit = it->second.begin(), vend = it->second.end();
while(vit != vend){
cout<<vit->c_str()<<"\t";
++vit;
}
cout<<endl;
++it;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> words;
ANAGRAM output;
populateWords(words);
groupAnagrams(words, output);
printAnagrams(output);
return 0;
}