1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! no_std support //! # Suffix Array //! Implementation of the [suffix array](https://www.researchgate.net/profile/Daricks_Wai_Hong_Chan/publication/221577802_Linear_Suffix_Array_Construction_by_Almost_Pure_Induced-Sorting/links/00b495318a21ba484f000000/Linear-Suffix-Array-Construction-by-Almost-Pure-Induced-Sorting.pdf?origin=publication_detail) //! construction of which is performed in linear time //! //! ## Examples //! //! ``` //! use suff_collections::{array::*, tree::*, lcp::*}; //! //! // let word = "Some word"; //! let word: &str = "Some word\0"; //! let find: &str = "word"; //! //! // construct suffix array //! // let sa = SuffixArray::<usize>::new_stack(word); //! // let sa = SuffixArray::<u8>::new(word); //! // let sa = SuffixArray::<u16>::new(word); //! // let sa = SuffixArray::<u32>::new(word); //! let sa = SuffixArray::<usize>::new(word); //! //! // construct lcp //! // lcp[i] = max_pref(sa[i], sa[i - 1]) && lcp.len() == sa.len() //! let lcp: LCP<usize> = sa.lcp(); //! //! // finds the entry position of the line 'find' in 'word' //! // O(|find| * log(|word|)) //! let res: Option<usize> = sa.find(find); //! //! // finds all the entry position of the line 'find' in 'word' //! // O(|find| * log(|word|)) //! let res_all: &[usize] = sa.find_all(find); //! //! // finds the entry position of the line 'find' in 'word' //! // O(|word|) //! let res: Option<usize> = sa.find_big(&sa.lcp(), find); //! //! // finds all the entry position of the line 'find' in 'word' //! // O(|word|) //! let res_all: &[usize] = sa.find_all_big(&sa.lcp(), find); //! //! // convert suffix array to suffix tree //! let st = SuffixTree::from(sa); //! ``` //! # Suffix Tree //! Implementation of the [suffix tree](https://web.stanford.edu/~mjkay/gusfield.pdf) //! construction of which is performed in linear time //! //! ## Examples //! //! ``` //! use suff_collections::{array::*, tree::*, lcp::*}; //! //! // let word = "Some word"; //! let word: &str = "Some word\0"; //! let find: &str = "word"; //! //! // construct suffix tree //! let st: SuffixTree = SuffixTree::new(word); //! //! // finds the entry position of the line 'find' in 'word' //! let res: Option<usize> = st.find(find); //! //! // construct lcp //! // lcp[i] = max_pref(sa[i], sa[i - 1]) && lcp.len() == sa.len() //! // let lcp: LCP<u8> = st.lcp::<u8>(); //! // let lcp: LCP<u16> = st.lcp::<u16>(); //! // let lcp: LCP<u32> = st.lcp::<u32>(); //! let lcp: LCP<usize> = st.lcp::<usize>(); //! //! // convert suffix tree to suffix array //! // let sa = SuffixArray::<u8>::from(st); //! // let sa = SuffixArray::<u16>::from(st); //! // let sa = SuffixArray::<u32>::from(st); //! let sa = SuffixArray::<usize>::from(st); //! ``` #![no_std] #[macro_use(vec)] extern crate alloc; pub mod array; pub mod lcp; pub mod tree; pub(crate) mod bit; use alloc::borrow::{Cow, ToOwned}; use alloc::vec::Vec; use core::str; fn canonic_word(word: &str) -> Cow<'_, str> { if word.as_bytes().last() == Some(&0) { Cow::from(word) } else { Cow::from( str::from_utf8( &word .as_bytes() .iter() .chain(&[0]) .copied() .collect::<Vec<_>>(), ) .unwrap() .to_owned(), ) } }