Skip to content

Commit e4a7e2d

Browse files
add trie (#28)
* add trie * fixes * nit * add type to doc * trie default nits
1 parent c5186cd commit e4a7e2d

File tree

4 files changed

+116
-0
lines changed

4 files changed

+116
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ path = "examples/data_structures/fenwick_yosupo.rs"
3030
name = "rmq"
3131
path = "examples/data_structures/rmq.rs"
3232

33+
[[example]]
34+
name = "trie"
35+
path = "examples/data_structures/trie.rs"
36+
3337
[[example]]
3438
name = "dijk_aizu"
3539
path = "examples/graphs/dijk_aizu.rs"

examples/data_structures/trie.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/all/ALDS1_4_C
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::trie::Trie;
5+
6+
fn main() {
7+
input! {
8+
n: usize,
9+
}
10+
11+
let mut trie = Trie::default();
12+
for _ in 0..n {
13+
input! {
14+
command: String,
15+
key: String,
16+
}
17+
18+
match command.as_str() {
19+
"insert" => {
20+
trie.insert(&key);
21+
}
22+
"find" => {
23+
if trie.find(&key) > 0 {
24+
println!("yes");
25+
} else {
26+
println!("no");
27+
}
28+
}
29+
_ => unreachable!(),
30+
}
31+
}
32+
}

src/data_structures/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
pub mod dsu;
33
pub mod fenwick;
44
pub mod rmq;
5+
pub mod trie;

src/data_structures/trie.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! # Trie
2+
3+
const ALPHABET_SIZE: usize = 26;
4+
const FIRST_CHAR: char = 'A';
5+
6+
struct Node {
7+
next: [Option<usize>; ALPHABET_SIZE],
8+
cnt_words: usize,
9+
}
10+
11+
impl Default for Node {
12+
fn default() -> Self {
13+
Node {
14+
next: [None; ALPHABET_SIZE],
15+
cnt_words: 0,
16+
}
17+
}
18+
}
19+
20+
/// # Example
21+
/// ```
22+
/// use programming_team_code_rust::data_structures::trie::Trie;
23+
///
24+
/// let mut trie = Trie::default();
25+
/// trie.insert("HELLO");
26+
/// trie.insert("HELLO");
27+
/// trie.insert("WORLD");
28+
/// assert_eq!(trie.find("HELLO"), 2);
29+
/// assert_eq!(trie.find("WORLD"), 1);
30+
/// assert_eq!(trie.find("WORLDS"), 0);
31+
/// ```
32+
pub struct Trie {
33+
t: Vec<Node>,
34+
}
35+
36+
impl Default for Trie {
37+
fn default() -> Self {
38+
Trie {
39+
t: vec![Node::default()],
40+
}
41+
}
42+
}
43+
44+
impl Trie {
45+
/// Insert a string into the Trie
46+
///
47+
/// # Complexity
48+
/// - Time: O(|s|)
49+
/// - Space: O(|s|)
50+
pub fn insert(&mut self, s: &str) {
51+
let mut v = 0;
52+
for ch in s.chars() {
53+
let idx = (ch as u8 - FIRST_CHAR as u8) as usize;
54+
if self.t[v].next[idx].is_none() {
55+
self.t[v].next[idx] = Some(self.t.len());
56+
self.t.push(Node::default());
57+
}
58+
v = self.t[v].next[idx].unwrap();
59+
}
60+
self.t[v].cnt_words += 1;
61+
}
62+
63+
/// Find the number of times a string appears in the Trie
64+
///
65+
/// # Complexity
66+
/// - Time: O(|s|)
67+
/// - Space: O(1)
68+
pub fn find(&self, s: &str) -> usize {
69+
let mut v = 0;
70+
for ch in s.chars() {
71+
let idx = (ch as u8 - FIRST_CHAR as u8) as usize;
72+
if self.t[v].next[idx].is_none() {
73+
return 0;
74+
}
75+
v = self.t[v].next[idx].unwrap();
76+
}
77+
self.t[v].cnt_words
78+
}
79+
}

0 commit comments

Comments
 (0)