是今天看到CareerCup上的问题:
Use the shorest unique prefix to represent each word in the array
input: ["zebra", "dog", "duck",”dot”]
output: {zebra: z, dog: do, duck: du}
input: [bearcat, bear]
output: {bearcat: bearc, bear: ""}
大意即,给出一系列单词,然后求每个单词的最短前缀表示,使得每个前缀表示都能唯一确定整个单词,第二个输入输出表明当单词的所有前缀都不能唯一地代表这个单词时,其前缀表示为空。
思路即将所有单词插入Trie中,然后找到第一个出现频率为1的前缀即可。
#include <cstring>
#include <exception>
#include <iostream>
#include <string>
using namespace std;
class WordNotFoundException : public exception{
private:
string description;
public:
WordNotFoundException(const string& word) : description(word + " not found"){}
~WordNotFoundException() throw() {}
virtual const char* what()const throw() {
return description.c_str();
}
};
class WordTrie{
private:
static const int MAX = 26;
struct TrieNode{
int freq;
bool eow;
TrieNode* ch[MAX];
};
TrieNode* root;
private:
bool isLeaf(const TrieNode* p)const{
for(int i = 0; i < MAX; ++i){
if(p->ch[i]) return false;
}
return true;
}
int getIndex(char c)const{
return c - 'a';
}
TrieNode* newNode()const{
TrieNode* p = new TrieNode;
memset(p, 0, sizeof(TrieNode));
return p;
}
void deleteTrie(TrieNode* p){
if(!p) return;
for(int i = 0; i < MAX; ++i) deleteTrie(p->ch[i]);
delete p;
}
public:
WordTrie(){
root = newNode();
}
~WordTrie(){
deleteTrie(root);
}
void insertWord(const string& word){
TrieNode* p = root;
int i = 0, len = word.size(), k;
for(; i < len; ++i){
k = getIndex(word[i]);
if(!p->ch[k]) p->ch[k] = newNode();
p = p->ch[k];
++p->freq;
}
p->eow = true;
}
bool findWord(const string& word)const{
TrieNode* p = root;
int i = 0, len = word.size(), k;
for(; i < len; ++i){
k = getIndex(word[i]);
if(!p->ch[k]) return false;
p = p->ch[k];
}
return p->eow;
}
string getPrefixRepresentation(const string& word) throw(WordNotFoundException){
if(!findWord(word))
throw WordNotFoundException(word);
TrieNode* p = root;
bool found = false;
int i = 0, len = word.size(), k;
for(; i < len && !found; ++i){
k = getIndex(word[i]);
if(p->ch[k]->freq < 2) found = true;
p = p->ch[k];
}
return isLeaf(p) ? word.substr(0, i) : "";
}
};
int main()
{
WordTrie dict;
string words[] = {"dog","done","good","go","gogo","gold","golf","why","which","while","zebra", "duck","dot"};
int i, n = sizeof(words) / sizeof(words[0]);
for(i = 0; i < n; ++i) dict.insertWord(words[i]);
for(i = 0; i < n; ++i){
try{
string rep = dict.getPrefixRepresentation(words[i]);
cout << words[i] << " -> " << rep << "\n";
} catch(WordNotFoundException& e){
cout << e.what() << "\n";
}
}
return 0;
}