-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtriehard.hpp
196 lines (163 loc) · 4.72 KB
/
triehard.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#ifndef TRIEHARD_HPP
#define TRIEHARD_HPP
#include "concepts.hpp"
#include <string>
#include <string.h>
#include <map>
#include <iostream>
#include <list>
#include <origin/sequence/concepts.hpp>
//LATER...
//TRINODE BASE and TRINODE
//Add a copy constructor and move constructor
//Copy for the nodes as well
//Look at map interface
/*
trieNode
Storage node utilized in trie structure
*/
template<typename K, typename V>
struct trieNode {
std::list<V> value;
std::map<K, trieNode<K, V>* > neighbors;
};
/*
trie
trie structure for mapping keys to values
current support is for string and char based keys
*/
template<typename K, typename V>
requires Equality_comparable< Value_type<K> >()
struct trie {
// Root trie node
trieNode< Value_type<K>, V >* head;
// Count of values contained within trie
size_t val_count;
trie(): head(new trieNode< Value_type<K>, V >) {}
~trie() {
delete head;
}
/*
INSERT FUNCTIONS
*/
// Add string based key value pair to trie
bool insert(const std::string& word, const V& val) {
return insert(std::begin(word), std::end(word), val);
}
// Add char* based key value pair to trie
bool insert(const char* word, const V& val) {
return insert(&word[0], &word[strlen(word)], val);
}
// Add key value part to trie via iterators
template<typename I>
requires origin::Forward_iterator<I>()
bool insert(I first, I last, const V& val) {
trieNode< Value_type<K>, V >* start = buildBranches(first, last);
if (!(start->value.empty()))
return false;
start->value.push_back(val);
++val_count;
return true;
}
/*
FETCH FUNCTIONS
*/
// Fetch value based on string key in trie
V* fetch(const std::string& word) {
return fetch(std::begin(word), std::end(word));
}
// Fetch value based on char* key in trie
V* fetch(const char* word) {
return fetch(&word[0], &word[strlen(word)]);
}
// Retrieval of values from trie based on key
// Used in place of [] operator due to time constraints
template<typename I>
requires origin::Forward_iterator<I>()
V* fetch(I first, I last) {
trieNode< Value_type<K>, V >* start = findNode(first, last);
if(start != NULL && !(start->value.empty()))
return &(start->value.front());
else
return NULL;
}
/*
ERASE FUNCTIONS
*/
// Erase value based on string key in trie
bool erase(const std::string& word) {
return erase(std::begin(word), std::end(word));
}
// Erase value based on char* key in trie
bool erase(const char* word) {
return erase(&word[0], &word[strlen(word)]);
}
// Remove value from trie
template<typename I>
requires origin::Forward_iterator<I>()
bool erase(I first, I last) {
trieNode< Value_type<K>, V >* start = findNode(first, last);
if (start == NULL || start->value.empty())
return false;
start->value.clear();
--val_count;
return true;
}
/*
COUNT FUNCTIONS
*/
// Find string based key in trie
size_t count(const std::string& word) {
return count(std::begin(word), std::end(word));
}
// Find char* based key in trie
size_t count(const char* word) {
return count(&word[0], &word[strlen(word)]);
}
// Determine if key is associated with a value
template<typename I>
requires origin::Forward_iterator<I>()
size_t count(I first, I last) {
trieNode< Value_type<K>, V >* start = findNode(first, last);
return (start != NULL && !(start->value.empty()));
}
// Return number of values in trie
size_t size() {
return val_count;
}
// Return whether trie contains values or is empty
bool empty() {
return (val_count == 0);
}
// Helper functions
private:
// Builds the branches necessary for an insert into the trie
template<typename I>
requires origin::Forward_iterator<I>()
trieNode< Value_type<K>, V >* buildBranches(I first, I last) {
trieNode< Value_type<K>, V >* start = head;
while (first != last) {
auto search = start->neighbors.find(*first);
if(search == start->neighbors.end())
start->neighbors.insert(std::make_pair(*first, new trieNode< Value_type<K>, V >));
start = start->neighbors[*first];
++first;
}
return start;
}
// Determines if a node exists along a path given two iterators
template<typename I>
requires origin::Forward_iterator<I>()
trieNode< Value_type<K>, V >* findNode(I first, I last) {
trieNode< Value_type<K>, V >* start = head;
while (first != last) {
auto search = start->neighbors.find(*first);
if(search == start->neighbors.end())
return NULL;
start = start->neighbors[*first];
++first;
}
return start;
}
};
#endif