pub fn new(patterns: impl IntoIterator<Item = impl IntoIterator<Item = C>>) -> Self {
        let mut trie = Trie::default();
        let pat_nodes: Vec<usize> = patterns.into_iter().map(|pat| trie.insert(pat)).collect();

        let mut pat_id = vec![None; trie.links.len()];
        for (i, node) in pat_nodes.into_iter().enumerate() {
            pat_id[node] = Some(i);
        }

        let mut fail = vec![0; trie.links.len()];
        let mut fast = vec![0; trie.links.len()];
        let mut q: VecDeque<usize> = trie.links[0].values().cloned().collect();

        while let Some(node) = q.pop_front() {
            for (ch, &child) in &trie.links[node] {
                let nx = Self::next(&trie, &fail, fail[node], &ch);
                fail[child] = nx;
                fast[child] = if pat_id[nx].is_some() { nx } else { fast[nx] };
                q.push_back(child);
            }
        }

        Self {
            trie,
            pat_id,
            fail,
            fast,
        }
    }
/// Precomputes the automaton that allows linear-time string matching.
/// If there are duplicate patterns, all but one copy will be ignored.
Precomputes the automaton that allows linear-time string matching.
If there are duplicate patterns, all but one copy will be ignored.
Precomputes the automaton that allows linear - time string matching . If there are duplicate patterns all but one copy will be ignored .
pub fn new(patterns: impl IntoIterator<Item = impl IntoIterator<Item = C>>) -> Self {
        let mut trie = Trie::default();
        let pat_nodes: Vec<usize> = patterns.into_iter().map(|pat| trie.insert(pat)).collect();
        let mut pat_id = vec![None; trie.links.len()];
        for (i, node) in pat_nodes.into_iter().enumerate() {
            pat_id[node] = Some(i);
        }
        let mut fail = vec![0; trie.links.len()];
        let mut fast = vec![0; trie.links.len()];
        let mut q: VecDeque<usize> = trie.links[0].values().cloned().collect();
        while let Some(node) = q.pop_front() {
            for (ch, &child) in &trie.links[node] {
                let nx = Self::next(&trie, &fail, fail[node], &ch);
                fail[child] = nx;
                fast[child] = if pat_id[nx].is_some() { nx } else { fast[nx] };
                q.push_back(child);
            }
        }
        Self {
            trie,
            pat_id,
            fail,
            fast,
        }
    }
pub fn new ( patterns : impl IntoIterator < Item = impl IntoIterator < Item = C > > ) -> Self { let mut trie = Trie :: default ( ) ; let pat_nodes : Vec < usize > = patterns . into_iter ( ) . map ( | pat | trie . insert ( pat ) ) . collect ( ) ; let mut pat_id = vec ! [ None trie links len ( ) ] ; for ( i , node ) in pat_nodes . into_iter ( ) . enumerate ( ) { pat_id [ node ] = Some ( i ) ; } let mut fail = vec ! [ 0 trie links len ( ) ] ; let mut fast = vec ! [ 0 trie links len ( ) ] ; let mut q : VecDeque < usize > = trie . links [ 0 ] . values ( ) . cloned ( ) . collect ( ) ; while let Some ( node ) = q . pop_front ( ) { for ( ch , & child ) in & trie . links [ node ] { let nx = Self :: next ( & trie , & fail , fail [ node ] , & ch ) ; fail [ child ] = nx ; fast [ child ] = if pat_id [ nx ] . is_some ( ) { nx } else { fast [ nx ] } ; q . push_back ( child ) ; } } Self { trie , pat_id , fail , fast , } }
Precomputes the automaton that allows linear-time string matching.
Precomputes the automaton that allows linear - time string matching .
patterns
impl IntoIterator<Item = impl IntoIterator<Item = C>>