Skip to content

fix(strings): avoid counting false matches in z-function search - #15302

Merged
cclauss merged 1 commit into
TheAlgorithms:masterfrom
Miladkhoshdel:fix/z-function-false-matches
Sep 12, 2026
Merged

fix(strings): avoid counting false matches in z-function search#15302
cclauss merged 1 commit into
TheAlgorithms:masterfrom
Miladkhoshdel:fix/z-function-false-matches

Conversation

@Miladkhoshdel

@Miladkhoshdel Miladkhoshdel commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Describe your change

find_pattern() previously inspected Z-values belonging to the pattern prefix, causing it to count matches that crossed the boundary between the pattern and input string.

This change limits match counting to Z-values corresponding to positions inside the input string.

For example, find_pattern("aa", "a") previously returned 1; it now correctly returns 0.

Fixes #15303

  • Add an algorithm?
  • Fix a bug or typo in an existing algorithm?
  • Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
  • Documentation change?

Checklist

  • I have read CONTRIBUTING.md.
  • This pull request is all my own work -- I have not plagiarized.
  • I know that pull requests will not be merged if they fail the automated tests.
  • This PR only changes one algorithm file. To ease review, please open separate PRs for separate algorithms.
  • All new Python files are placed inside an existing directory.
  • All filenames are in all lowercase characters with no spaces or dashes.
  • All functions and variable names follow Python naming conventions.
  • All function parameters and return values are annotated with Python type hints.
  • All functions have doctests that pass the automated testing.
  • All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
  • If this pull request resolves one or more open issues, then the description above includes the issue number(s) with a closing keyword: "Fixes #ISSUE-NUMBER".

@algorithms-keeper algorithms-keeper Bot added awaiting reviews This PR is ready to be reviewed enhancement This PR modified some existing files labels Sep 12, 2026
@Miladkhoshdel

Copy link
Copy Markdown
Contributor Author

I added one minimal regression doctest alongside the fix because the existing doctests did not expose this bug. The new case reproduces the incorrect boundary-crossing match and verifies that the fix works. Although the template recommends separating code and test changes, keeping this regression test with the fix ensures the corrected behavior is documented and protected against future regressions.

@cclauss

cclauss commented Sep 12, 2026

Copy link
Copy Markdown
Member

@priya-sundaram-dev, please review.

@priya-sundaram-dev

Copy link
Copy Markdown
Contributor

Reviewed — the fix is correct and well-targeted. 👍

The root cause is exactly as described: find_pattern scans the Z-array of pattern + input_str, but the first len(pattern) entries are positions inside the pattern prefix, so a self-overlapping pattern (e.g. "aa") produces a Z-value ≥ len(pattern) there and gets miscounted. Slicing z_result[pattern_length:] restricts counting to positions that actually start in input_str, which is the right fix — the valid match-start range is precisely indices pattern_length .. pattern_length + len(input_str) - 1.

I ran the patched file locally (ruff-free, plain python -m doctest) and all doctests pass. A few edge checks to confirm the fix doesn't regress overlapping matches:

find_pattern("aa", "a")     -> 0   # was 1 (the bug)
find_pattern("aa", "aaa")   -> 2   # overlapping occurrences still counted
find_pattern("a", "aaaa")   -> 4
find_pattern("abr", "abracadabra") -> 2
find_pattern("xz", "zxxzxxz")      -> 2

The refactor to sum(value >= pattern_length for value in z_result[pattern_length:]) is also a nice readability win and hoists len(pattern) out of the loop. Combining the one-line regression doctest with the fix is sensible here since the existing doctests didn't exercise the boundary case; the added find_pattern("aa", "a") locks in the corrected behavior. LGTM.

(Disclosure: I'm Priya Sundaram, an AI software agent; a human reviews my substantive work.)

@algorithms-keeper algorithms-keeper Bot removed the awaiting reviews This PR is ready to be reviewed label Sep 12, 2026
@cclauss
cclauss merged commit d0370db into TheAlgorithms:master Sep 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement This PR modified some existing files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

find_pattern() counts false matches across the pattern-input boundary

3 participants