1+ //! This module provides a generic implementation of a Trie (prefix tree).
2+ //! A Trie is a tree-like data structure that is commonly used to store sequences of keys
3+ //! (such as strings, integers, or other iterable types) where each node represents one element
4+ //! of the key, and values can be associated with full sequences.
5+
16use std:: collections:: HashMap ;
27use std:: hash:: Hash ;
38
9+ /// A single node in the Trie structure, representing a key and an optional value.
410#[ derive( Debug , Default ) ]
511struct Node < Key : Default , Type : Default > {
12+ /// A map of children nodes where each key maps to another `Node`.
613 children : HashMap < Key , Node < Key , Type > > ,
14+ /// The value associated with this node, if any.
715 value : Option < Type > ,
816}
917
18+ /// A generic Trie (prefix tree) data structure that allows insertion and lookup
19+ /// based on a sequence of keys.
1020#[ derive( Debug , Default ) ]
1121pub struct Trie < Key , Type >
1222where
1323 Key : Default + Eq + Hash ,
1424 Type : Default ,
1525{
26+ /// The root node of the Trie, which does not hold a value itself.
1627 root : Node < Key , Type > ,
1728}
1829
@@ -21,12 +32,21 @@ where
2132 Key : Default + Eq + Hash ,
2233 Type : Default ,
2334{
35+ /// Creates a new, empty `Trie`.
36+ ///
37+ /// # Returns
38+ /// A `Trie` instance with an empty root node.
2439 pub fn new ( ) -> Self {
2540 Self {
2641 root : Node :: default ( ) ,
2742 }
2843 }
2944
45+ /// Inserts a value into the Trie, associating it with a sequence of keys.
46+ ///
47+ /// # Arguments
48+ /// - `key`: An iterable sequence of keys (e.g., characters in a string or integers in a vector).
49+ /// - `value`: The value to associate with the sequence of keys.
3050 pub fn insert ( & mut self , key : impl IntoIterator < Item = Key > , value : Type )
3151 where
3252 Key : Eq + Hash ,
@@ -38,60 +58,98 @@ where
3858 node. value = Some ( value) ;
3959 }
4060
61+ /// Retrieves a reference to the value associated with a sequence of keys, if it exists.
62+ ///
63+ /// # Arguments
64+ /// - `key`: An iterable sequence of keys (e.g., characters in a string or integers in a vector).
65+ ///
66+ /// # Returns
67+ /// An `Option` containing a reference to the value if the sequence of keys exists in the Trie,
68+ /// or `None` if it does not.
4169 pub fn get ( & self , key : impl IntoIterator < Item = Key > ) -> Option < & Type >
4270 where
4371 Key : Eq + Hash ,
4472 {
4573 let mut node = & self . root ;
4674 for c in key {
47- if node. children . contains_key ( & c) {
48- node = node. children . get ( & c) . unwrap ( )
49- } else {
50- return None ;
51- }
75+ node = node. children . get ( & c) ?;
5276 }
5377 node. value . as_ref ( )
5478 }
5579}
5680
5781#[ cfg( test) ]
5882mod tests {
59-
6083 use super :: * ;
6184
6285 #[ test]
63- fn test_insertion ( ) {
86+ fn test_insertion_and_retrieval_with_strings ( ) {
6487 let mut trie = Trie :: new ( ) ;
65- assert_eq ! ( trie. get( "" . chars( ) ) , None ) ;
6688
6789 trie. insert ( "foo" . chars ( ) , 1 ) ;
90+ assert_eq ! ( trie. get( "foo" . chars( ) ) , Some ( & 1 ) ) ;
6891 trie. insert ( "foobar" . chars ( ) , 2 ) ;
92+ assert_eq ! ( trie. get( "foobar" . chars( ) ) , Some ( & 2 ) ) ;
93+ assert_eq ! ( trie. get( "foo" . chars( ) ) , Some ( & 1 ) ) ;
94+ trie. insert ( "bar" . chars ( ) , 3 ) ;
95+ assert_eq ! ( trie. get( "bar" . chars( ) ) , Some ( & 3 ) ) ;
96+ assert_eq ! ( trie. get( "baz" . chars( ) ) , None ) ;
97+ assert_eq ! ( trie. get( "foobarbaz" . chars( ) ) , None ) ;
98+ }
6999
100+ #[ test]
101+ fn test_insertion_and_retrieval_with_integers ( ) {
70102 let mut trie = Trie :: new ( ) ;
71- assert_eq ! ( trie. get( vec![ 1 , 2 , 3 ] ) , None ) ;
72103
73104 trie. insert ( vec ! [ 1 , 2 , 3 ] , 1 ) ;
74- trie. insert ( vec ! [ 3 , 4 , 5 ] , 2 ) ;
105+ assert_eq ! ( trie. get( vec![ 1 , 2 , 3 ] ) , Some ( & 1 ) ) ;
106+ trie. insert ( vec ! [ 1 , 2 , 3 , 4 , 5 ] , 2 ) ;
107+ assert_eq ! ( trie. get( vec![ 1 , 2 , 3 , 4 , 5 ] ) , Some ( & 2 ) ) ;
108+ assert_eq ! ( trie. get( vec![ 1 , 2 , 3 ] ) , Some ( & 1 ) ) ;
109+ trie. insert ( vec ! [ 10 , 20 , 30 ] , 3 ) ;
110+ assert_eq ! ( trie. get( vec![ 10 , 20 , 30 ] ) , Some ( & 3 ) ) ;
111+ assert_eq ! ( trie. get( vec![ 4 , 5 , 6 ] ) , None ) ;
112+ assert_eq ! ( trie. get( vec![ 1 , 2 , 3 , 4 , 5 , 6 ] ) , None ) ;
75113 }
76114
77115 #[ test]
78- fn test_get ( ) {
116+ fn test_empty_trie ( ) {
117+ let trie: Trie < char , i32 > = Trie :: new ( ) ;
118+
119+ assert_eq ! ( trie. get( "foo" . chars( ) ) , None ) ;
120+ assert_eq ! ( trie. get( "" . chars( ) ) , None ) ;
121+ }
122+
123+ #[ test]
124+ fn test_insert_empty_key ( ) {
125+ let mut trie: Trie < char , i32 > = Trie :: new ( ) ;
126+
127+ trie. insert ( "" . chars ( ) , 42 ) ;
128+ assert_eq ! ( trie. get( "" . chars( ) ) , Some ( & 42 ) ) ;
129+ assert_eq ! ( trie. get( "foo" . chars( ) ) , None ) ;
130+ }
131+
132+ #[ test]
133+ fn test_overlapping_keys ( ) {
79134 let mut trie = Trie :: new ( ) ;
80- trie. insert ( "foo" . chars ( ) , 1 ) ;
81- trie. insert ( "foobar" . chars ( ) , 2 ) ;
82- trie. insert ( "bar" . chars ( ) , 3 ) ;
83- trie. insert ( "baz" . chars ( ) , 4 ) ;
84135
85- assert_eq ! ( trie. get( "foo" . chars( ) ) , Some ( & 1 ) ) ;
86- assert_eq ! ( trie. get( "food" . chars( ) ) , None ) ;
136+ trie. insert ( "car" . chars ( ) , 1 ) ;
137+ trie. insert ( "cart" . chars ( ) , 2 ) ;
138+ trie. insert ( "carter" . chars ( ) , 3 ) ;
139+ assert_eq ! ( trie. get( "car" . chars( ) ) , Some ( & 1 ) ) ;
140+ assert_eq ! ( trie. get( "cart" . chars( ) ) , Some ( & 2 ) ) ;
141+ assert_eq ! ( trie. get( "carter" . chars( ) ) , Some ( & 3 ) ) ;
142+ assert_eq ! ( trie. get( "care" . chars( ) ) , None ) ;
143+ }
87144
145+ #[ test]
146+ fn test_partial_match ( ) {
88147 let mut trie = Trie :: new ( ) ;
89- trie. insert ( vec ! [ 1 , 2 , 3 , 4 ] , 1 ) ;
90- trie. insert ( vec ! [ 42 ] , 2 ) ;
91- trie. insert ( vec ! [ 42 , 6 , 1000 ] , 3 ) ;
92- trie. insert ( vec ! [ 1 , 2 , 4 , 16 , 32 ] , 4 ) ;
93148
94- assert_eq ! ( trie. get( vec![ 42 , 6 , 1000 ] ) , Some ( & 3 ) ) ;
95- assert_eq ! ( trie. get( vec![ 43 , 44 , 45 ] ) , None ) ;
149+ trie. insert ( "apple" . chars ( ) , 10 ) ;
150+ assert_eq ! ( trie. get( "app" . chars( ) ) , None ) ;
151+ assert_eq ! ( trie. get( "appl" . chars( ) ) , None ) ;
152+ assert_eq ! ( trie. get( "apple" . chars( ) ) , Some ( & 10 ) ) ;
153+ assert_eq ! ( trie. get( "applepie" . chars( ) ) , None ) ;
96154 }
97155}
0 commit comments