Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 64f3755

Browse files
committed
Z algorithm without mutating Z[..]
1 parent cf2906b commit 64f3755

File tree

1 file changed

+18
-19
lines changed

1 file changed

+18
-19
lines changed

‎src/string_proc.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ impl<C: std::hash::Hash + Eq> Trie<C> {
4949
pub struct Matcher<'a, C: Eq> {
5050
/// The string pattern to search for.
5151
pub pattern: &'a [C],
52-
/// KMP match failure automaton. fail[i] is the length of the longest
53-
/// proper prefix-suffix of pattern[0..=i].
52+
/// KMP match failure automaton: fail[i] is the length of the longest
53+
/// string that's both a proper prefix and a proper suffix of pattern[0..=i].
5454
pub fail: Vec<usize>,
5555
}
5656

@@ -316,18 +316,18 @@ pub fn palindromes(text: &[impl Eq]) -> Vec<usize> {
316316
pal
317317
}
318318

319-
/// Z algorithm for computing an array Z[..], where Z[i] is the length of the
320-
/// longest text substring starting from index i that is **also a prefix** of
321-
/// the text.
319+
/// Z algorithm: computes the array Z[..], where Z[i] is the length of the
320+
/// longest text prefix of text[i..] that is **also a prefix** of text.
322321
///
323-
/// This runs in O(n) time. It can be embedded in a larger algorithm, or used
324-
/// for string searching as an alternative to KMP above.
322+
/// It runs in O(n) time, maintaining the invariant that l <= i and
323+
/// text[0..r-l] == text[l..r]. It can be embedded in a larger algorithm,
324+
/// or used for string searching as an alternative to KMP.
325325
///
326326
/// # Example
327327
///
328328
/// ```
329329
/// use contest_algorithms::string_proc::z_algorithm;
330-
/// let z = z_algorithm("ababbababbabababbabababbababbaba".as_bytes());
330+
/// let z = z_algorithm(b"ababbababbabababbabababbababbaba");
331331
/// assert_eq!(
332332
/// z,
333333
/// vec![
@@ -338,19 +338,18 @@ pub fn palindromes(text: &[impl Eq]) -> Vec<usize> {
338338
/// ```
339339
pub fn z_algorithm(text: &[impl Eq]) -> Vec<usize> {
340340
let n = text.len();
341-
let (mut l, mut r) = (0,0);
342-
let mut z = vec![0; n];
343-
z[0] = n;
341+
let (mut l, mut r) = (1,1);
342+
let mut z = Vec::with_capacity(n);
343+
z.push(n);
344344
for i in 1..n {
345-
if i < r {
346-
z[i] = min(r - i, z[i - l]);
347-
}
348-
while i + z[i] < n && text[i + z[i]] == text[z[i]] {
349-
z[i] += 1;
350-
}
351-
if i + z[i] > r {
345+
if r > i + z[i - l] {
346+
z.push(z[i - l]);
347+
} else {
352348
l = i;
353-
r = i + z[i];
349+
while r < i || (r < n && text[r - i] == text[r]) {
350+
r += 1;
351+
}
352+
z.push(r - i);
354353
}
355354
}
356355
z

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /