ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Longest Common Subsequence (Dynamic Programming)

MATLAB

Goal -- WPM

Ready
Exercise Algorithm Area
1function [lcs, len] = longestCommonSubsequence(text1, text2)
2%LONGESTCOMMONSUBSEQUENCE Computes the Longest Common Subsequence (LCS) of two strings.
3% [lcs, len] = longestCommonSubsequence(text1, text2) returns the LCS
4% string 'lcs' and its length 'len' for the input strings 'text1' and 'text2'.
5% It uses a dynamic programming approach.
6
7% Input validation
8if ~ischar(text1) || ~ischar(text2)
9error('Inputs text1 and text2 must be character arrays (strings).');
10end
11
12m = length(text1);
13n = length(text2);
14
15% Initialize DP table
16% dpTable(i, j) will store the length of the LCS of text1(1..i) and text2(1..j)
17dpTable = zeros(m + 1, n + 1);
18
19% Fill the DP table
20for i = 1:m
21for j = 1:n
22if text1(i) == text2(j)
23% If characters match, LCS length increases by 1 from the diagonal
24dpTable(i + 1, j + 1) = dpTable(i, j) + 1;
25else
26% If characters do not match, take the maximum from the top or left cell
27dpTable(i + 1, j + 1) = max(dpTable(i, j + 1), dpTable(i + 1, j));
28end
29end
30end
31
32% The length of the LCS is in the bottom-right cell
33len = dpTable(m + 1, n + 1);
34
35% Backtrack to reconstruct the LCS string
36lcs = '';
37i = m;
38j = n;
39
40while i > 0 && j > 0
41if text1(i) == text2(j)
42% If characters match, this character is part of the LCS
43lcs = [text1(i), lcs]; % Prepend character
44i = i - 1;
45j = j - 1;
46elseif dpTable(i, j + 1) > dpTable(i + 1, j)
47% If the value from the top cell is greater, move up
48i = i - 1;
49else
50% Otherwise, move left
51j = j - 1;
52end
53end
54
55end
56
57function testLCS()
58%TESTLCS Helper function to test the longestCommonSubsequence function.
59
60% Test case 1: Basic strings
61text1 = 'AGGTAB';
62text2 = 'GXTXAYB';
63[lcs, len] = longestCommonSubsequence(text1, text2);
64fprintf('Text1: %s\n', text1);
65fprintf('Text2: %s\n', text2);
66fprintf('LCS: %s, Length: %d\n\n', lcs, len);
67% Expected: LCS: GTAB, Length: 4
68
69% Test case 2: No common subsequence
70text1 = 'ABC';
71text2 = 'DEF';
72[lcs, len] = longestCommonSubsequence(text1, text2);
73fprintf('Text1: %s\n', text1);
74fprintf('Text2: %s\n', text2);
75fprintf('LCS: %s, Length: %d\n\n', lcs, len);
76% Expected: LCS: , Length: 0
77
78% Test case 3: One string is empty
79text1 = 'ABCD';
80text2 = '';
81[lcs, len] = longestCommonSubsequence(text1, text2);
82fprintf('Text1: %s\n', text1);
83fprintf('Text2: %s\n', text2);
84fprintf('LCS: %s, Length: %d\n\n', lcs, len);
85% Expected: LCS: , Length: 0
86
87% Test case 4: Identical strings
88text1 = 'ABCDEFG';
89text2 = 'ABCDEFG';
90[lcs, len] = longestCommonSubsequence(text1, text2);
91fprintf('Text1: %s\n', text1);
92fprintf('Text2: %s\n', text2);
93fprintf('LCS: %s, Length: %d\n\n', lcs, len);
94% Expected: LCS: ABCDEFG, Length: 7
95
96% Test case 5: Strings with repeated characters
97text1 = 'ABAZDC';
98text2 = 'BACBAD';
99[lcs, len] = longestCommonSubsequence(text1, text2);
100fprintf('Text1: %s\n', text1);
101fprintf('Text2: %s\n', text2);
102fprintf('LCS: %s, Length: %d\n\n', lcs, len);
103% Expected: LCS: ABAD, Length: 4
104
105end
Algorithm description viewbox

Longest Common Subsequence (Dynamic Programming)

Algorithm description:

This algorithm finds the longest subsequence common to two given strings. A subsequence is formed by deleting zero or more characters from a string without changing the order of the remaining characters. This is a fundamental problem in bioinformatics (e.g., DNA sequence alignment) and text comparison.

Algorithm explanation:

The `longestCommonSubsequence` function uses dynamic programming to solve the LCS problem. It constructs a 2D table `dpTable` where `dpTable(i, j)` stores the length of the LCS of the first `i` characters of `text1` and the first `j` characters of `text2`. The recurrence relation is: if `text1(i) == text2(j)`, then `dpTable(i, j) = dpTable(i-1, j-1) + 1`; otherwise, `dpTable(i, j) = max(dpTable(i-1, j), dpTable(i, j-1))`. After filling the table, the length of the LCS is `dpTable(m, n)`. The actual LCS string is reconstructed by backtracking from `dpTable(m, n)`, moving up or left based on the values in the table, and prepending characters when a match is found. The time complexity is O(m*n) for filling the table and O(m+n) for backtracking, resulting in an overall O(m*n) complexity. The space complexity is O(m*n) for the DP table. Edge cases include empty strings, identical strings, and strings with no common characters.

Pseudocode:

function longestCommonSubsequence(text1, text2):
  m = length(text1)
  n = length(text2)
  dpTable = 2D array of size (m+1) x (n+1), initialized to 0

  for i from 1 to m:
    for j from 1 to n:
      if text1[i-1] == text2[j-1]: // Using 0-based indexing for strings here
        dpTable[i][j] = dpTable[i-1][j-1] + 1
      else:
        dpTable[i][j] = max(dpTable[i-1][j], dpTable[i][j-1])

  len = dpTable[m][n]
  lcs = ""
  i = m
  j = n

  while i > 0 and j > 0:
    if text1[i-1] == text2[j-1]:
      lcs = text1[i-1] + lcs
      i = i - 1
      j = j - 1
    else if dpTable[i-1][j] > dpTable[i][j-1]:
      i = i - 1
    else:
      j = j - 1

  return lcs, len