Rust 如何将尾部递归重写为一个循环?
我编写了前缀树的一个简单变体:Rust 如何将尾部递归重写为一个循环?,rust,Rust,我编写了前缀树的一个简单变体: struct Trie { data: Vec<Option<Trie>> } impl Trie { pub fn new() -> Trie { let mut data = Vec::with_capacity(26); for _ in 0..26 { data.push(None); } Trie { data: dat
struct Trie {
data: Vec<Option<Trie>>
}
impl Trie {
pub fn new() -> Trie {
let mut data = Vec::with_capacity(26);
for _ in 0..26 {
data.push(None);
}
Trie { data: data }
}
pub fn add(&mut self, word: &str) {
if word.len() != 0 {
let idx = Trie::char_idx(word.char_at(0));
let word_suffix = word.slice_from(1);
if self.data[idx].is_none() {
self.data[idx] = Some(Trie::new());
}
self.data[idx].as_mut().unwrap().add(word_suffix)
}
}
pub fn contain(&self, word: &str) -> bool {
if word.len() == 0 {
true
} else {
match self.data[Trie::char_idx(word.char_at(0))] {
Some(ref next) => next.contain(word.slice_from(1)),
None => false
}
}
}
fn char_idx(chr: char) -> usize {
(chr as u32 - 97) as usize
}
}
我能做些什么呢?我记得我读过其他提出相同概念问题的问题,但我现在找不到它们。也许一个善良的灵魂会把他们联系在一起 话虽如此,本文汇编:
pub fn add(&mut self, word: &str) {
let mut current = self;
for chr in word.chars() {
current = {
let tmp = current;
let idx = Trie::char_idx(chr);
if tmp.data[idx].is_none() {
tmp.data[idx] = Some(Trie::new());
}
tmp.data[idx].as_mut().unwrap()
}
}
}
我的总体想法是围绕当前的事实展开工作。在for循环内部,我创建了一个新的词法作用域,然后将current
重新加载为tmp
。我们在tmp
上进行工作,最终返回一个引用,然后将其放回current
a似乎起到了作用:
pub fn add(&mut self, word: &str) {
word.chars().fold(
self,
|current, chr| {
let idx = Trie::char_idx(chr);
if current.data[idx].is_none() {
current.data[idx] = Some(Trie::new());
}
current.data[idx].as_mut().unwrap()
});
}
更多的高尔夫。。。你不需要一个新的作用域,只要你把一些东西移回一个变量,你就可以在一个循环中离开它。此外,可变自参数:
pub fn add(&mut self, word: &str) {
word.chars().fold(
self,
|current, chr| {
let idx = Trie::char_idx(chr);
if current.data[idx].is_none() {
current.data[idx] = Some(Trie::new());
}
current.data[idx].as_mut().unwrap()
});
}