use std::collections::HashMap;
#[derive(Debug)]
struct TrieNode {
children: HashMap<char, Box<TrieNode>>,
is_word: bool,
}
impl TrieNode {
fn new() -> Self {
TrieNode {
children: HashMap::new(),
is_word: false,
}
}
}
struct Trie {
root: TrieNode,
}
impl Trie {
fn new() -> Self {
Trie {
root: TrieNode::new(),
}
}
fn insert(&mut self, word: &str) {
let mut node = &mut self.root;
for ch in word.chars() {
node = node.children.entry(ch).or_insert_with(|| Box::new(TrieNode::new())).as_mut();
}
node.is_word = true;
}
fn starts_with(&self, prefix: &str) -> Vec<String> {
let mut node = &self.root;
for ch in prefix.chars() {
if let Some(next_node) = node.children.get(&ch) {
node = next_node;
} else {
return vec![];
}
}
let mut results = Vec::new();
Self::collect_words(node, prefix.to_string(), &mut results);
results
}
fn collect_words(node: &TrieNode, prefix: String, results: &mut Vec<String>) {
if node.is_word {
results.push(prefix.clone());
}
for (ch, child) in &node.children {
let mut new_prefix = prefix.clone();
new_prefix.push(*ch);
Self::collect_words(child, new_prefix, results);
}
}
}
fn main() {
let words = vec!["apple", "bat"];
let prefix = "ap";
// Build trie
let mut trie = Trie::new();
for word in &words {
trie.insert(word);
}
// Search prefix in trie
let trie_results = trie.starts_with(prefix);
println!("Trie words with prefix '{}': {:?}", prefix, trie_results);
// Hash map stores full words
let mut map: HashMap<String, bool> = HashMap::new();
for word in &words {
map.insert(word.to_string(), true);
}
// Search prefix in hash map by checking all keys
let mut map_results = Vec::new();
for key in map.keys() {
if key.starts_with(prefix) {
map_results.push(key.clone());
}
}
println!("HashMap words with prefix '{}': {:?}", prefix, map_results);
}
node = node.children.entry(ch).or_insert_with(|| Box::new(TrieNode::new())).as_mut();
advance or create node for each letter in insert
if let Some(next_node) = node.children.get(&ch) { node = next_node; } else { return vec![]; }
advance node for each prefix letter or stop if missing
Self::collect_words(node, prefix.to_string(), &mut results);
collect all words under prefix node recursively
if node.is_word { results.push(prefix.clone()); }
add word to results when end of word reached
for key in map.keys() { if key.starts_with(prefix) { map_results.push(key.clone()); } }
check each hash map key for prefix match
Trie words with prefix 'ap': ["apple"]
HashMap words with prefix 'ap': ["apple"]