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>
impl<T> MultipleStringSearch<T>
pub fn new(texts: Vec<Vec<T>>) -> Self
pub fn texts(&self) -> &[Vec<T>]
pub fn longest_common_prefix( &self, a: (usize, Range<usize>), b: (usize, Range<usize>), ) -> usize
pub fn compare( &self, a: (usize, Range<usize>), b: (usize, Range<usize>), ) -> Ordering
pub fn range(&self, pattern: &[T]) -> Range<usize>
pub fn positions( &self, range: Range<usize>, ) -> impl DoubleEndedIterator<Item = (usize, usize)> + '_
pub fn kth_substrings(&self) -> MultipleKthSubstrings<'_, T>
Sourcefn to_global_range(&self, (index, range): (usize, Range<usize>)) -> Range<usize>
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 }Sourcefn suffix_len(&self, a: usize) -> usize
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§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more