-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathtrie.hpp
92 lines (77 loc) · 2.04 KB
/
trie.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// LGPL 3 or higher Robert Burner Schadek [email protected]
#ifndef SWEET_TRIE_HPP
#define SWEET_TRIE_HPP
//#include <unordered_map>
#include <map>
#include <ostream>
template<typename K, typename V, typename C>
class Trie;
template<typename K, typename V, typename C>
class Entry;
template<typename K, typename V, typename C>
std::ostream& operator<<(std::ostream&, const Trie<K,V,C>&);
template<typename K, typename V, typename C>
std::ostream& operator<<(std::ostream&, const Entry<K,V,C>&);
template<typename K, typename V, typename C>
struct Entry {
friend std::ostream& operator<< <>(std::ostream&, const Entry<K,V,C>&);
std::map<K,Entry,C> map;
V value;
bool isValue;
int32_t depth;
inline Entry() : isValue(false), depth(0) {}
inline Entry(const int32_t d) : isValue(false), depth(d) {}
};
template<typename K, typename V, typename C = std::less<K>>
class Trie {
public:
typedef Entry<K,V,C> TrieEntry;
private:
TrieEntry entries;
public:
friend std::ostream& operator<< <>(std::ostream&, const Trie<K,V,C>&);
Trie() : entries(0) {}
template<typename B, typename E>
bool insert(B first, E end, V value) {
TrieEntry* cur = &entries;
for(; first != end; ++first) {
auto next = cur->map.find(*first);
if(next == cur->map.end()) {
cur->map.insert(std::make_pair(*first, TrieEntry(cur->depth+1)));
}
next = cur->map.find(*first);
cur = &(next->second);
}
if(cur->isValue) {
return false;
} else {
cur->value = value;
cur->isValue = true;
return true;
}
}
inline TrieEntry& getRoot() {
return entries;
}
inline const TrieEntry& getRoot() const {
return entries;
}
};
template<typename K, typename V, typename C>
std::ostream& operator<<(std::ostream& os, const Trie<K,V,C>& t) {
os<<"Trie:";
os<<t.getRoot();
return os;
}
template<typename K, typename V, typename C>
std::ostream& operator<<(std::ostream& os, const Entry<K,V,C>& t) {
if(t.isValue) {
os<<t.value;
}
os<<std::endl;
for(auto& it : t.map) {
os<<std::string(it.second.depth*2, ' ')<<it.first<<":"<<it.second;
}
return os;
}
#endif