Skip to content

feat: add multiple longest common subsequence (MLCS-APP) - #1070

Open
Gaspardcode wants to merge 1 commit into
TheAlgorithms:masterfrom
Gaspardcode:feat/multiple-longest-common-subsequence
Open

Gaspardcode wants to merge 1 commit into
TheAlgorithms:masterfrom
Gaspardcode:feat/multiple-longest-common-subsequence

Conversation

@Gaspardcode

Copy link
Copy Markdown

Description

Adds multiple_longest_common_subsequence in src/string: finds a longest common subsequence of any number of strings (the classic DP only handles two efficiently, MLCS is NP-hard in general).

It implements MLCS-APP from A Fast Heuristic Search Algorithm for Finding the Longest Common Subsequence of Multiple Strings (Wang, Pan, Shang, Korkin, AAAI 2010) — paper, an A* variant over the matches of the strings:

  • h(p) = min of the suffix tables M(i,i+1)[p_i][p_i+1] (only the d − 1 consecutive tables, as in the paper), an upper bound of the remaining LCS
  • f(p) = g(p) + h(p), points ordered by f then h in a BinaryHeap
  • the successors are found in O(d) per letter with the MT lookup table
  • each layer keeps the points with y − c ≤ f(p) and at most k of them, with c = 20 and k = 2000 (the values used in the paper)

Two details go slightly beyond the pseudocode so that the result is always valid and as long as possible:

  • g(q) is only updated through a longer path (as in MLCS-A*), so the parent chain of a point never gets shorter
  • a point is returned only when no remaining point has a higher f (the condition of Theorem 1), and a point without any successor also ends a subsequence, since h is only an upper bound (e.g. ["BB", "BBC", "BC"] has h = 1 at the single match but no successor)

Tests check the length of the result and that it is a subsequence of every input, since several LCS may exist. Edge cases: no string, a single string, empty strings, no common letter, unicode.
I also cross-checked it locally against an exact DP on 21,300 random inputs (2 to 4 strings, alphabets of 3 and 4 letters): the result was optimal in every case.

This supersedes #861 (closed as stale); its review comments are addressed (Option<usize> instead of a sentinel, Context methods, BinaryHeap, link to doc/paper.pdf).

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • I ran cargo clippy --all -- -D warnings just before my last commit and fixed any issue that was found.
  • I ran cargo fmt just before my last commit.
  • I ran cargo test just before my last commit and all tests passed.
  • I added my algorithm to the corresponding mod.rs file within its own folder, and in any parent folder(s).
  • I added my algorithm to DIRECTORY.md with the correct link.
  • I checked COUNTRIBUTING.md and my code follows its guidelines.

The whole MLCS test module runs in ~20 ms.

🤖 Generated with Claude Code

Finds a longest common subsequence of any number of strings with the
MLCS-APP algorithm (Wang et al., AAAI 2010), an A* variant:
- heuristic built from the d - 1 suffix tables M(i,i+1), as in the paper
- each layer keeps the points with y - c <= f(p), at most k of them
  (c = 20 and k = 2000, the values of the paper)
- g(q) is only updated through a longer path, as in MLCS-A*
- a point is returned only when no other point can beat it (Theorem 1),
  and a point without successor also ends a subsequence, since h is
  only an upper bound

Supersedes TheAlgorithms#861.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Gaspardcode
Gaspardcode requested a review from imp2002 as a code owner October 3, 2026 14:32
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.07407% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.88%. Comparing base (2345c66) to head (f5ead9d).

Files with missing lines Patch % Lines
src/string/multiple_longest_common_subsequence.rs 99.07% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1070      +/-   ##
==========================================
- Coverage   95.89%   95.88%   -0.02%     
==========================================
  Files         396      397       +1     
  Lines       30440    30656     +216     
==========================================
+ Hits        29191    29395     +204     
- Misses       1249     1261      +12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants