好长时间没写blog了,写一篇表示我还活着,还在看代码,还在准备笔试和面试。。。
兄弟的单词就是两个或多个单词有相同的字母,只是字母顺序不同,例如:abfs 和fabs。找到所给单词的兄弟单词。
方案一:使用数据结构 map
代码:
#include
#include
#include
方案二:使用trie树。trie树又称字典树,在面试题中关于“字符串”与“数字串”类型的问题中高频出现,非常实用。对于兄弟单词,兄弟单词公用一个key自不必说,只是trie的节点结构应该多出一个域list,用来存储key对应的兄弟单词。具体节点结构应该为:
struct TrieNode
{
bool isAWord;//is a word
TrieNode* next[BRANCHNUM];
std::vector browords;
};
代码:
/*-----BrotherTrie.h-----*/
#ifndef BROTHERTRIE_H
#define BROTHERTRIE_H
#include
#include
#define BRANCHNUM 26
/*trie node*/
struct TrieNode
{
bool isAWord;//is a word
TrieNode* next[BRANCHNUM];
std::vector browords;
TrieNode():isAWord(false)
{
std::memset(next,NULL,sizeof(next));
}
};
/*trie class*/
class BroTrie
{
public:
TrieNode* root;
BroTrie() {root = new TrieNode();}
/*insert a word to brother trie*/
void insertAWord(const char* key, const char* word)
{
TrieNode* location = root;
while(*key)
{
if(location->next[*key - 'a'] == NULL)
{
TrieNode* tmp = new TrieNode();
location->next[*key - 'a'] = tmp;
}
location = location->next[*key - 'a'];
++key;
}
location->isAWord = true;
location->browords.push_back(word);
}
void outputBroWords(TrieNode* location)
{
if(location->isAWord)
{
std::vector::iterator it = location->browords.begin();
for(; it != location->browords.end(); ++it)
printf("%s ",*it);
printf("\n");
}
for(int i = 0; i < BRANCHNUM; ++i)
if(location->next[i] != NULL)
outputBroWords(location->next[i]);
delete location;
}
};
#endif
/*-----BrotherTrie.cpp-----*/
#include
#include"BrotherTrie.h"
using namespace std;
int cmp(const void* p, const void* q)
{
return (*(char*)p) - (*(char*)q);
}
int main()
{
BroTrie broWords;
string words[10] = {"abc", "bca", "cba", "fgdes", "edss",
"ssde", "fffg", "fgff", "gfff", "sffdswe"};
char* key; char* word;
for(int i = 0; i < 10; ++i)
{
word = &words[i][0];
int len = words[i].length();
key = new char[len+1];
strcpy(key, word);
qsort(key, len, sizeof(char), cmp);
broWords.insertAWord(key, word);
}
broWords.outputBroWords(broWords.root);
return 0;
}