Skip to content

Commit

Permalink
Merge pull request #2 from pacak/master
Browse files Browse the repository at this point in the history
A few goodies
  • Loading branch information
vemonet authored Aug 22, 2024
2 parents 1c9e3cf + 2fc27a4 commit e51ddba
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#![doc = include_str!("../README.md")]

#[doc(hidden)]
pub mod error;
#[doc(hidden)]
pub mod trie;
#[doc(hidden)]
pub mod trie_node;

pub use trie::Trie;
pub use error::TrieError;

#[doc(inline)]
pub use trie::{Trie, TrieIterator};
62 changes: 62 additions & 0 deletions src/trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,43 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
}
}

/// Finds the longest prefix and it's length in the `Trie` for a given string.
///
/// # Example
///
/// ```rust
/// use ptrie::Trie;
///
/// let mut trie = Trie::default();
/// assert_eq!(trie.find_longest_prefix_len("http://purl.obolibrary.org/obo/DOID_1234".bytes()), None);
/// trie.insert("http://purl.obolibrary.org/obo/DOID_".bytes(), "doid");
/// trie.insert("http://purl.obolibrary.org/obo/".bytes(), "obo");
///
/// assert_eq!(trie.find_longest_prefix_len("http://purl.obolibrary.org/obo/DOID_1234".bytes()), Some((36, &"doid")));
/// assert_eq!(trie.find_longest_prefix_len("http://purl.obolibrary.org/obo/1234".bytes()), Some((31, &"obo")));
/// assert_eq!(trie.find_longest_prefix_len("notthere".bytes()), None);
/// assert_eq!(trie.find_longest_prefix_len("httno".bytes()), None);
/// ```
pub fn find_longest_prefix_len<I: Iterator<Item = K>>(&self, key: I) -> Option<(usize, &V)> {
{
let mut current = &self.root;
let mut len = 0;
let mut last_value: Option<(usize, &V)> = None;
for k in key {
if let Some((_, next_node)) = current.children.iter().find(|(key, _)| key == &k) {
len += 1;
if next_node.value.is_some() {
last_value = next_node.value.as_ref().map(|v| (len, v));
}
current = next_node;
} else {
break;
}
}
last_value
}
}

/// Returns a list of all strings in the `Trie` that start with the given prefix.
///
/// # Example
Expand Down Expand Up @@ -293,6 +330,14 @@ impl<K: Eq + Ord + Clone, V: Clone> Trie<K, V> {
}
}

impl<'a, K: Clone + Ord, V: Clone> IntoIterator for &'a Trie<K, V> {
type IntoIter = TrieIterator<'a, K, V>;
type Item = (std::vec::Vec<K>, V);
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}

/// Implement the `Default` trait for `Trie` since we have a constructor that does not need arguments
impl<T: Eq + Ord + Clone, U: Clone> Default for Trie<T, U> {
fn default() -> Self {
Expand Down Expand Up @@ -334,3 +379,20 @@ impl<'a, K: Eq + Ord + Clone, V: Clone> Iterator for TrieIterator<'a, K, V> {
None
}
}

#[cfg(test)]
mod tests {
#[test]

fn longest_prefix() {
use super::Trie;

let mut trie = Trie::default();
trie.insert("hello".bytes(), 1u8);
trie.insert("h".bytes(), 2u8);

assert_eq!(trie.find_longest_prefix_len("hello".bytes()), Some((5, &1)));
assert_eq!(trie.find_longest_prefix_len("h".bytes()), Some((1, &2)));
assert_eq!(trie.find_longest_prefix_len("he".bytes()), Some((1, &2)));
}
}

0 comments on commit e51ddba

Please sign in to comment.