diff --git a/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstring.test.js b/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstring.test.js index a24c0df5..8c1cb207 100644 --- a/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstring.test.js +++ b/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstring.test.js @@ -7,6 +7,8 @@ describe('longestCommonSubstring', () => { expect(longestCommonSubstring('', 'ABC')).toBe(''); expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC'); expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC'); + expect(longestCommonSubstring('sea', 'eat')).toBe('ea'); + expect(longestCommonSubstring('algorithms', 'rithm')).toBe('rithm'); expect(longestCommonSubstring( 'Algorithms and data structures implemented in JavaScript', 'Here you may find Algorithms and data structures that are implemented in JavaScript', diff --git a/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstringRecursive.test.js b/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstringRecursive.test.js new file mode 100644 index 00000000..d8428033 --- /dev/null +++ b/src/algorithms/string/longest-common-substring/__test__/longestCommonSubstringRecursive.test.js @@ -0,0 +1,17 @@ +import longestCommonSubstring from '../longestCommonSubstringRecursive'; + +describe('longestCommonSubstringRecursive', () => { + it('should find longest common substring between two strings', () => { + expect(longestCommonSubstring('', '')).toBe(''); + expect(longestCommonSubstring('ABC', '')).toBe(''); + expect(longestCommonSubstring('', 'ABC')).toBe(''); + expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC'); + expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABCA'); + expect(longestCommonSubstring('sea', 'eat')).toBe('ea'); + expect(longestCommonSubstring('algorithms', 'rithm')).toBe('rithm'); + expect(longestCommonSubstring( + 'Algorithms and data structures implemented in JavaScript', + 'Here you may find Algorithms and data structures that are implemented in JavaScript', + )).toBe('Algorithms and data structures implemented in JavaScript'); + }); +}); diff --git a/src/algorithms/string/longest-common-substring/longestCommonSubstring.js b/src/algorithms/string/longest-common-substring/longestCommonSubstring.js index 1d68ede9..6afeccf3 100644 --- a/src/algorithms/string/longest-common-substring/longestCommonSubstring.js +++ b/src/algorithms/string/longest-common-substring/longestCommonSubstring.js @@ -1,4 +1,6 @@ /** + * Longest Common Substring (LCS) (Dynamic Programming Approach). + * * @param {string} string1 * @param {string} string2 * @return {string} diff --git a/src/algorithms/string/longest-common-substring/longestCommonSubstringRecursive.js b/src/algorithms/string/longest-common-substring/longestCommonSubstringRecursive.js new file mode 100644 index 00000000..88cb08aa --- /dev/null +++ b/src/algorithms/string/longest-common-substring/longestCommonSubstringRecursive.js @@ -0,0 +1,36 @@ +/* eslint-disable no-param-reassign */ +/** + * Longest Common Substring (LCS) (Recursive Approach). + * + * @param {string} string1 + * @param {string} string2 + * @return {number} + */ +export default function longestCommonSubstringRecursive(string1, string2) { + /** + * + * @param {string} s1 + * @param {string} s2 + * @return {string} - returns the LCS (Longest Common Substring) + */ + const lcs = (s1, s2, memo = {}) => { + if (!s1 || !s2) return ''; + + if (memo[`${s1}:${s2}`]) return memo[`${s1}:${s2}`]; + + if (s1[0] === s2[0]) { + return s1[0] + lcs(s1.substring(1), s2.substring(1), memo); + } + + const nextLcs1 = lcs(s1.substring(1), s2, memo); + const nextLcs2 = lcs(s1, s2.substring(1), memo); + + const nextLongest = nextLcs1.length >= nextLcs2.length ? nextLcs1 : nextLcs2; + + memo[`${s1}:${s2}`] = nextLongest; + + return nextLongest; + }; + + return lcs(string1, string2); +}