Skip to content

Commit afd60bd

Browse files
committed
add: Stream of Characters
1 parent 963251b commit afd60bd

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

β€Ž1032-stream-of-characters.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
use std::cell::RefCell;
2+
use std::collections::VecDeque;
3+
4+
#[derive(Default)]
5+
struct TrieNode {
6+
is_word: bool,
7+
children: [Option<Box<TrieNode>>; 26],
8+
}
9+
10+
impl TrieNode {
11+
fn new() -> Self {
12+
Default::default()
13+
}
14+
15+
fn insert(&mut self, word: Vec<u8>) {
16+
let mut curr = self;
17+
for ch in word.into_iter().map(|ch| (ch - b'a') as usize) {
18+
let children = &mut curr.children[ch];
19+
curr = children.get_or_insert_with(|| Box::new(TrieNode::new()))
20+
}
21+
curr.is_word = true;
22+
}
23+
}
24+
25+
struct StreamChecker {
26+
trie: TrieNode,
27+
last_queried: RefCell<VecDeque<u8>>,
28+
max_word_length: usize,
29+
}
30+
31+
impl StreamChecker {
32+
fn new(words: Vec<String>) -> Self {
33+
let max_word_length = words.iter().map(|word| word.len()).max().unwrap_or(0_usize);
34+
let last_queried = VecDeque::with_capacity(max_word_length);
35+
36+
let mut trie = TrieNode::new();
37+
for word in words {
38+
let mut word = word.into_bytes();
39+
word.reverse();
40+
trie.insert(word);
41+
}
42+
43+
Self {
44+
trie,
45+
last_queried: RefCell::new(last_queried),
46+
max_word_length,
47+
}
48+
}
49+
50+
fn query(&self, letter: char) -> bool {
51+
self.last_queried.borrow_mut().push_back(letter as u8);
52+
if self.last_queried.borrow().len() > self.max_word_length {
53+
self.last_queried.borrow_mut().pop_front();
54+
}
55+
56+
let mut curr = &self.trie;
57+
for &ch in self.last_queried.borrow().iter().rev() {
58+
curr = match &curr.children[(ch - b'a') as usize] {
59+
Some(trie) if trie.is_word => return true,
60+
Some(trie) => trie,
61+
None => break,
62+
};
63+
}
64+
false
65+
}
66+
}
67+
68+
fn main() {
69+
let sc = StreamChecker::new(vec!["cd".to_string(), "f".to_string(), "kl".to_string()]);
70+
assert_eq!(false, sc.query('a'));
71+
assert_eq!(false, sc.query('b'));
72+
assert_eq!(false, sc.query('c'));
73+
assert_eq!(true, sc.query('d'));
74+
assert_eq!(false, sc.query('e'));
75+
assert_eq!(true, sc.query('f'));
76+
assert_eq!(false, sc.query('g'));
77+
assert_eq!(false, sc.query('h'));
78+
assert_eq!(false, sc.query('i'));
79+
assert_eq!(false, sc.query('j'));
80+
assert_eq!(false, sc.query('k'));
81+
assert_eq!(true, sc.query('l'));
82+
83+
let sc = StreamChecker::new(vec!["abcde".to_string(), "ef".to_string()]);
84+
assert_eq!(false, sc.query('a'));
85+
assert_eq!(false, sc.query('b'));
86+
assert_eq!(false, sc.query('c'));
87+
assert_eq!(false, sc.query('d'));
88+
assert_eq!(true, sc.query('e'));
89+
assert_eq!(true, sc.query('f'));
90+
assert_eq!(false, sc.query('g'));
91+
}

0 commit comments

Comments
 (0)