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
use std::cell::RefCell; use std::cmp::Eq; use std::cmp::PartialEq; use std::collections::HashMap; use std::hash::Hash; use std::rc::Rc; #[derive(Debug, Clone)] pub enum Leaf<T> { End(T), Nil, } impl<T: PartialEq> PartialEq for Leaf<T> { fn eq(&self, other: &Self) -> bool { match self { Leaf::End(d) => match other { Leaf::End(od) => d == od, Leaf::Nil => false, }, Leaf::Nil => match other { Leaf::End(_) => false, Leaf::Nil => true, }, } } } #[derive(Debug)] pub struct Node<T: Eq + Hash + Clone> { pub node: HashMap<T, Rc<RefCell<Node<T>>>>, pub leaf: Leaf<T>, } pub trait Trie<T: Eq + Hash + Clone> { fn insert_seq(node: Rc<RefCell<Node<T>>>, words: &[T], leaf: Leaf<T>) { let (index, mut m_node) = Node::find_last_node(node.clone(), &words); for word in &words[index..] { m_node = Node::add_node(m_node.clone(), word.to_owned()); } Node::add_leaf(m_node, leaf); } fn get_leaf(node: Rc<RefCell<Node<T>>>, words: &[T]) -> Leaf<T> { let length = words.len(); let (index, node) = Node::find_last_node(node.clone(), words); if index + 1 == length { let m_node = node.borrow(); m_node.leaf.to_owned() } else { Leaf::Nil } } fn find_node(node: Rc<RefCell<Node<T>>>, word: &T) -> (bool, Rc<RefCell<Node<T>>>) { let m_node = node.borrow(); match m_node.node.get(word) { Some(mm_node) => (true, mm_node.clone()), None => (false, node.clone()), } } fn find_last_node(node: Rc<RefCell<Node<T>>>, words: &[T]) -> (usize, Rc<RefCell<Node<T>>>) { let mut m_node = node.clone(); let mut out_index = 0; for (index, word) in words.iter().enumerate() { let (label, mm_node) = Node::find_node(m_node.clone(), word); if label { out_index = index + 1; m_node = mm_node; } } (out_index, m_node.clone()) } fn add_leaf(node: Rc<RefCell<Node<T>>>, leaf: Leaf<T>) -> bool { let mut m_node = node.borrow_mut(); m_node.leaf = leaf; true } fn add_node(node: Rc<RefCell<Node<T>>>, node_data: T) -> Rc<RefCell<Node<T>>> { let mut m_node = node.borrow_mut(); let new_node = Node::new(); m_node.node.insert(node_data, new_node.clone()); new_node.clone() } } impl<T: Eq + Hash + Clone> Trie<T> for Node<T> {} impl<T: Eq + Hash + Clone> Node<T> { pub fn new() -> Rc<RefCell<Node<T>>> { Rc::new(RefCell::new(Node { node: HashMap::new(), leaf: Leaf::Nil, })) } } #[test] fn name() { let node = Node::new(); let seq = vec!["你".to_string(), "我".to_string(), "他".to_string()]; let seq1 = vec!["你".to_string(), "我".to_string()]; Node::insert_seq(node.clone(), &seq, Leaf::End("intention".to_string())); let leaf = Node::get_leaf(node.clone(), &seq1); assert_ne!(leaf, Leaf::End("intention".to_string())); }