Skip to main content

MultipleStringSearch

Struct MultipleStringSearch 

Source
pub struct MultipleStringSearch<T> {
    texts: Vec<Vec<T>>,
    offsets: Vec<usize>,
    position_map: Vec<(usize, usize)>,
    search: StringSearch<Delimited<T>>,
}

Fields§

§texts: Vec<Vec<T>>§offsets: Vec<usize>§position_map: Vec<(usize, usize)>§search: StringSearch<Delimited<T>>

Implementations§

Source§

impl<T> MultipleStringSearch<T>
where T: Ord + Clone,

Source

pub fn new(texts: Vec<Vec<T>>) -> Self

Source

pub fn texts(&self) -> &[Vec<T>]

Source

pub fn longest_common_prefix( &self, a: (usize, Range<usize>), b: (usize, Range<usize>), ) -> usize

Source

pub fn compare( &self, a: (usize, Range<usize>), b: (usize, Range<usize>), ) -> Ordering

Source

pub fn range(&self, pattern: &[T]) -> Range<usize>

Source

pub fn positions( &self, range: Range<usize>, ) -> impl DoubleEndedIterator<Item = (usize, usize)> + '_

Source

pub fn kth_substrings(&self) -> MultipleKthSubstrings<'_, T>

Source

fn to_global_range(&self, (index, range): (usize, Range<usize>)) -> Range<usize>

Examples found in repository?
crates/competitive/src/string/string_search.rs (line 322)
317    pub fn longest_common_prefix(
318        &self,
319        a: (usize, Range<usize>),
320        b: (usize, Range<usize>),
321    ) -> usize {
322        let a = self.to_global_range(a);
323        let b = self.to_global_range(b);
324        self.search.longest_common_prefix(a, b)
325    }
326
327    pub fn compare(&self, a: (usize, Range<usize>), b: (usize, Range<usize>)) -> Ordering {
328        let a = self.to_global_range(a);
329        let b = self.to_global_range(b);
330        self.search.compare(a, b)
331    }
332
333    pub fn range(&self, pattern: &[T]) -> Range<usize> {
334        let pattern = DelimitedPattern { pattern };
335        let left = self.search.bound_prefix(&pattern, false);
336        let right = self.search.bound_prefix(&pattern, true);
337        left..right
338    }
339
340    pub fn positions(
341        &self,
342        range: Range<usize>,
343    ) -> impl DoubleEndedIterator<Item = (usize, usize)> + '_ {
344        debug_assert!(range.start <= range.end);
345        debug_assert!(range.end <= self.position_map.len());
346        range.map(move |i| self.position_map[self.search.suffix_array[i]])
347    }
348
349    pub fn kth_substrings(&self) -> MultipleKthSubstrings<'_, T> {
350        MultipleKthSubstrings::new(self)
351    }
352
353    fn to_global_range(&self, (index, range): (usize, Range<usize>)) -> Range<usize> {
354        debug_assert!(index < self.texts.len());
355        let len = self.texts[index].len();
356        debug_assert!(range.start <= range.end && range.end <= len);
357        let base = self.offsets[index];
358        base + range.start..base + range.end
359    }
360
361    fn suffix_len(&self, a: usize) -> usize {
362        let (text_idx, pos) = self.position_map[self.search.suffix_array[a]];
363        self.texts[text_idx].len() - pos
364    }
365}
366
367#[derive(Debug)]
368pub struct MultipleKthSubstrings<'a, T> {
369    search: &'a MultipleStringSearch<T>,
370    prefix: Vec<u64>,
371}
372
373impl<'a, T> MultipleKthSubstrings<'a, T>
374where
375    T: Ord + Clone,
376{
377    fn new(search: &'a MultipleStringSearch<T>) -> Self {
378        let n = search.search.text.len();
379        let mut prefix = Vec::with_capacity(n);
380        prefix.push(0);
381        let mut total = 0u64;
382        for i in 1..=n {
383            let len = search.suffix_len(i);
384            let prev_len = search.suffix_len(i - 1);
385            let lcp_prev = search.search.lcp_array[i - 1].min(len).min(prev_len);
386            total += (len - lcp_prev) as u64;
387            prefix.push(total);
388        }
389        Self { search, prefix }
390    }
391
392    pub fn kth_distinct_substring(&self, k: u64) -> Option<(usize, Range<usize>)> {
393        let idx = self.prefix.partition_point(|&x| x <= k);
394        if idx == self.prefix.len() {
395            return None;
396        }
397        let (text_idx, pos) = self.search.position_map[self.search.search.suffix_array[idx]];
398        let len = self.search.suffix_len(idx) - (self.prefix[idx] - k) as usize + 1;
399        Some((text_idx, pos..pos + len))
400    }
401
402    pub fn index_of_distinct_substring(&self, (text_idx, range): (usize, Range<usize>)) -> u64 {
403        debug_assert!(text_idx < self.search.texts.len());
404        debug_assert!(range.start < range.end && range.end <= self.search.texts[text_idx].len());
405        let m = range.len();
406        let range = self.search.to_global_range((text_idx, range));
407        let idx = self.search.search.geq_suffix(range);
408        let len = self.search.suffix_len(idx);
409        let prev_len = self.search.suffix_len(idx - 1);
410        let lcp_prev = self.search.search.lcp_array[idx - 1].min(len).min(prev_len);
411        self.prefix[idx - 1] + (m - lcp_prev - 1) as u64
412    }
Source

fn suffix_len(&self, a: usize) -> usize

Examples found in repository?
crates/competitive/src/string/string_search.rs (line 383)
377    fn new(search: &'a MultipleStringSearch<T>) -> Self {
378        let n = search.search.text.len();
379        let mut prefix = Vec::with_capacity(n);
380        prefix.push(0);
381        let mut total = 0u64;
382        for i in 1..=n {
383            let len = search.suffix_len(i);
384            let prev_len = search.suffix_len(i - 1);
385            let lcp_prev = search.search.lcp_array[i - 1].min(len).min(prev_len);
386            total += (len - lcp_prev) as u64;
387            prefix.push(total);
388        }
389        Self { search, prefix }
390    }
391
392    pub fn kth_distinct_substring(&self, k: u64) -> Option<(usize, Range<usize>)> {
393        let idx = self.prefix.partition_point(|&x| x <= k);
394        if idx == self.prefix.len() {
395            return None;
396        }
397        let (text_idx, pos) = self.search.position_map[self.search.search.suffix_array[idx]];
398        let len = self.search.suffix_len(idx) - (self.prefix[idx] - k) as usize + 1;
399        Some((text_idx, pos..pos + len))
400    }
401
402    pub fn index_of_distinct_substring(&self, (text_idx, range): (usize, Range<usize>)) -> u64 {
403        debug_assert!(text_idx < self.search.texts.len());
404        debug_assert!(range.start < range.end && range.end <= self.search.texts[text_idx].len());
405        let m = range.len();
406        let range = self.search.to_global_range((text_idx, range));
407        let idx = self.search.search.geq_suffix(range);
408        let len = self.search.suffix_len(idx);
409        let prev_len = self.search.suffix_len(idx - 1);
410        let lcp_prev = self.search.search.lcp_array[idx - 1].min(len).min(prev_len);
411        self.prefix[idx - 1] + (m - lcp_prev - 1) as u64
412    }

Trait Implementations§

Source§

impl<T: Debug> Debug for MultipleStringSearch<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for MultipleStringSearch<T>

§

impl<T> RefUnwindSafe for MultipleStringSearch<T>
where T: RefUnwindSafe,

§

impl<T> Send for MultipleStringSearch<T>
where T: Send,

§

impl<T> Sync for MultipleStringSearch<T>
where T: Sync,

§

impl<T> Unpin for MultipleStringSearch<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for MultipleStringSearch<T>

§

impl<T> UnwindSafe for MultipleStringSearch<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToArrayVecScalar for T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.