Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to fix error in trie implementation in rust?

I’m trying to implement a trie in rust to learn the language, especially around recursive structures. In the process, I"m seeing that the add_word method gives me an error. The implementation is

use std::array;
#[derive(Default)]
pub struct Trie {
    is_end: bool,
    pub children: [Option<Box<Trie>>; 26],
}

impl Trie {
    pub fn new() -> Box<Self> {
        Box::new(Trie {
            is_end: false,
            children: array::from_fn(|_| None),
        })
    }

    pub fn starts_with(&self, s: &str) -> bool {
        if s.is_empty() {
            return true;
        }
        let child = &self.children[(s.as_bytes()[0] - b'a') as usize];
        if child.is_none() {
            return false;
        }
        child
            .as_ref()
            .unwrap()
            .starts_with(s.get(1..).unwrap_or_default())
    }

    pub fn add_word(&mut self, s: &str) {
        if s.is_empty() {
            self.is_end = true;
        }
        let index = (s.as_bytes()[0] - b'a') as usize;
        let child = &self.children[index];
        if child.is_none() {
            return;
        }
        child
            .as_ref()
            .unwrap()
            .add_word(s.get(1..).unwrap_or_default());
    }
}

and the error is cannot borrow data in a & reference as mutable cannot borrow as mutable. I’m open to other fixes not directly related to my question that may yield more idiomatic rust code. Like, I believe I could have used unwrap_or_default in places but my attempts led to a bunch of other scary errors that didn’t get easily resolved by following clippy’s advice.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Try This:

use std::array;

#[derive(Default)]
pub struct Trie {
    is_end: bool,
    pub children: Vec<Option<Box<Trie>>>,
}

impl Trie {
    pub fn new() -> Box<Self> {
        Box::new(Trie {
            is_end: false,
            children: vec![None; 26],
        })
    }

    pub fn starts_with(&self, s: &str) -> bool {
        if s.is_empty() {
            return true;
        }
        let child = &self.children[(s.as_bytes()[0] - b'a') as usize];
        if child.is_none() {
            return false;
        }
        child
            .as_ref()
            .unwrap()
            .starts_with(s.get(1..).unwrap_or_default())
    }

    pub fn add_word(&mut self, s: &str) {
        if s.is_empty() {
            self.is_end = true;
        } else {
            let index = (s.as_bytes()[0] - b'a') as usize;
            let child = self.children.get_mut(index).unwrap();
            if child.is_none() {
                *child = Some(Trie::new());
            }
            child.as_mut().unwrap().add_word(s.get(1..).unwrap_or_default());
        }
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading