高级农民
- 积分
- 4631
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2013-11-24
- 最后登录
- 1970-1-1
|
贴一个我写的实现。其实不难,核心就是两个*_recur函数,但是确实觉得电面那点时间连写带讲太不现实了,哪怕做过。
#include <iostream>
#include <cctype>
#include <vector>
#include <string>
using namespace std;
class CamelSearchEng {
struct Node { //trie node
//lazy impl. for children, ideally would only allocate space for alphabetical chars
Node* children[256] = { nullptr };
bool is_word = false;
~Node() {
for (int k = 0; k < 256; ++k) delete children[k];
}
};
Node* root;
public:
//allocate trie
CamelSearchEng(vector<string> words) {
root = new Node;
for (const string& word : words) {
Node* t = root;
for (char c : word) {
if (t->children[c] == nullptr) t->children[c] = new Node;
t = t->children[c];
}
t->is_word = true;
}
};
// deallocate trie
~CamelSearchEng() {
delete root;
};
// search CamelPattern
vector<string> search(const string& pattern) const {
vector<string> result;
string word;
search_recur(pattern, 0, root, word, result);
return result;
}
void append_words_recur(Node* t, string& word, vector<string>& result) const {
if (t->is_word) result.push_back(word);
for (char c = 'a'; c <= 'z'; ++c) {
if (t->children[c]) {
word.push_back(c);
append_words_recur(t->children[c], word, result);
word.pop_back();
}
}
for (char c = 'A'; c <= 'Z'; ++c) {
if (t->children[c]) {
word.push_back(c);
append_words_recur(t->children[c], word, result);
word.pop_back();
}
}
}
void search_recur(const string& pattern, int first, Node* t, string& word, vector<string>& result) const {
size_t word_len = word.size();
while (first < pattern.size() && islower(pattern[first]) && t) {
t = t->children[pattern[first]];
word.push_back(pattern[first]);
++first;
}
if (t == nullptr) {//no match
; //stop searching
}
else if (first == pattern.size()) { //found a matched prefix
append_words_recur(t, word, result); //append all words under t
}
else { //pattern[first] is upper
char c = pattern[first];
for (int ch = 'a'; ch <= 'z'; ++ch) {
if (t->children[ch]) search_recur(pattern, first, t->children[ch], word, result);
}
if (t->children[c]) {
word.push_back(c);
search_recur(pattern, first+1, t->children[c], word, result);
}
}
//restore word for back tracing
word.resize(word_len);
}
};
void test(const CamelSearchEng& eng, const string& query) {
cout << "query: " << query << endl;
vector<string> result = eng.search(query);
for (const string& str: result) cout << str << " ";
cout << endl << endl;
}
int main() {
vector<string> dictionary{"FooBar", "FootBall", "FooToo", "FiBa"};
CamelSearchEng eng(dictionary);
test(eng, "F");
test(eng, "FB");
test(eng, "FT");
test(eng, "FoBa");
test(eng, "FBa");
test(eng, "FiB");
return 0;
}
补充内容 (2016-9-19 03:45):
写构造函数API的时候脑残了传了vector<string>,应该传const vector<string>&的
不过不影响正确性 |
|