Skip to content

Instantly share code, notes, and snippets.

@AlphaModder
Created January 9, 2022 03:04
Show Gist options
  • Save AlphaModder/c953105725710ca03bd3b9319d752f2d to your computer and use it in GitHub Desktop.
Save AlphaModder/c953105725710ca03bd3b9319d752f2d to your computer and use it in GitHub Desktop.
struct TrieNode {
sib: Option<(char, usize)>,
child: Option<(char, usize)>,
terminal: bool,
}
pub struct Trie { nodes: Vec<TrieNode> }
impl Trie {
fn root(&self) -> &TrieNode { &self.nodes[0] }
fn find_or_insert_child(&mut self, node: usize, c: char) -> usize {
let next = self.nodes.len();
let mut where_to_insert = &mut self.nodes[node].child;
loop {
match *where_to_insert {
Some((c2, idx)) if c == c2 => return idx,
Some((_, idx)) => where_to_insert = &mut self.nodes[idx].sib,
None => {
*where_to_insert = Some((c, next));
self.nodes.push(TrieNode { sib: None, child: None, terminal: false });
return next
}
}
}
}
pub fn insert(&mut self, str: &str) {
let mut idx = 0; // root
for char in str.chars() {
idx = self.find_or_insert_child(idx, char);
}
self.nodes[idx].terminal = true;
}
fn find_child(&self, node: &TrieNode, c: char) -> Option<&TrieNode> {
let mut current = &node.child;
while let Some((c2, idx)) = current {
let node = &self.nodes[*idx];
if c == *c2 { return Some(node) }
current = &node.sib;
}
None
}
pub fn contains(&self, str: &str) -> bool {
let node = self.root();
for char in str.chars() {
node = match self.find_child(node, char) {
Some(child) => child,
None => return false,
}
}
node.terminal
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment