mirror of
https://github.moeyy.xyz/https://github.com/trekhleb/javascript-algorithms.git
synced 2024-12-26 23:21:18 +08:00
Add more unicode related tests to longestCommonSubstring algorithm.
This commit is contained in:
parent
82ac89b16a
commit
af64d12a23
@ -7,6 +7,16 @@ describe('longestCommonSubstring', () => {
|
|||||||
expect(longestCommonSubstring('', 'ABC')).toBe('');
|
expect(longestCommonSubstring('', 'ABC')).toBe('');
|
||||||
expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC');
|
expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC');
|
||||||
expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC');
|
expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC');
|
||||||
|
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 ');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle unicode correctly', () => {
|
||||||
expect(longestCommonSubstring('𐌵𐌵**ABC', '𐌵𐌵--ABC')).toBe('ABC');
|
expect(longestCommonSubstring('𐌵𐌵**ABC', '𐌵𐌵--ABC')).toBe('ABC');
|
||||||
|
expect(longestCommonSubstring('𐌵𐌵**A', '𐌵𐌵--A')).toBe('𐌵𐌵');
|
||||||
|
expect(longestCommonSubstring('A买B时', '买B时GD')).toBe('买B时');
|
||||||
|
expect(longestCommonSubstring('After test买时 case', 'another_test买时')).toBe('test买时');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
* @param {string} s1
|
* @param {string} string1
|
||||||
* @param {string} s2
|
* @param {string} string2
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
export default function longestCommonSubstring(s1, s2) {
|
export default function longestCommonSubstring(string1, string2) {
|
||||||
// transform s1 & s2 into arrays to allow handling unicodes as single caracter.
|
// Convert strings to arrays to treat unicode symbols length correctly.
|
||||||
const [a1, a2] = [s1, s2].map(s => Array.from(s));
|
// For example:
|
||||||
|
// '𐌵'.length === 2
|
||||||
|
// [...'𐌵'].length === 1
|
||||||
|
const s1 = [...string1];
|
||||||
|
const s2 = [...string2];
|
||||||
|
|
||||||
// Init the matrix of all substring lengths to use Dynamic Programming approach.
|
// Init the matrix of all substring lengths to use Dynamic Programming approach.
|
||||||
const substringMatrix = Array(a2.length + 1).fill(null).map(() => {
|
const substringMatrix = Array(s2.length + 1).fill(null).map(() => {
|
||||||
return Array(a1.length + 1).fill(null);
|
return Array(s1.length + 1).fill(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fill the first row and first column with zeros to provide initial values.
|
// Fill the first row and first column with zeros to provide initial values.
|
||||||
for (let columnIndex = 0; columnIndex <= a1.length; columnIndex += 1) {
|
for (let columnIndex = 0; columnIndex <= s1.length; columnIndex += 1) {
|
||||||
substringMatrix[0][columnIndex] = 0;
|
substringMatrix[0][columnIndex] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let rowIndex = 0; rowIndex <= a2.length; rowIndex += 1) {
|
for (let rowIndex = 0; rowIndex <= s2.length; rowIndex += 1) {
|
||||||
substringMatrix[rowIndex][0] = 0;
|
substringMatrix[rowIndex][0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,9 +30,9 @@ export default function longestCommonSubstring(s1, s2) {
|
|||||||
let longestSubstringColumn = 0;
|
let longestSubstringColumn = 0;
|
||||||
let longestSubstringRow = 0;
|
let longestSubstringRow = 0;
|
||||||
|
|
||||||
for (let rowIndex = 1; rowIndex <= a2.length; rowIndex += 1) {
|
for (let rowIndex = 1; rowIndex <= s2.length; rowIndex += 1) {
|
||||||
for (let columnIndex = 1; columnIndex <= a1.length; columnIndex += 1) {
|
for (let columnIndex = 1; columnIndex <= s1.length; columnIndex += 1) {
|
||||||
if (a1[columnIndex - 1] === a2[rowIndex - 1]) {
|
if (s1[columnIndex - 1] === s2[rowIndex - 1]) {
|
||||||
substringMatrix[rowIndex][columnIndex] = substringMatrix[rowIndex - 1][columnIndex - 1] + 1;
|
substringMatrix[rowIndex][columnIndex] = substringMatrix[rowIndex - 1][columnIndex - 1] + 1;
|
||||||
} else {
|
} else {
|
||||||
substringMatrix[rowIndex][columnIndex] = 0;
|
substringMatrix[rowIndex][columnIndex] = 0;
|
||||||
@ -53,7 +57,7 @@ export default function longestCommonSubstring(s1, s2) {
|
|||||||
let longestSubstring = '';
|
let longestSubstring = '';
|
||||||
|
|
||||||
while (substringMatrix[longestSubstringRow][longestSubstringColumn] > 0) {
|
while (substringMatrix[longestSubstringRow][longestSubstringColumn] > 0) {
|
||||||
longestSubstring = a1[longestSubstringColumn - 1] + longestSubstring;
|
longestSubstring = s1[longestSubstringColumn - 1] + longestSubstring;
|
||||||
longestSubstringRow -= 1;
|
longestSubstringRow -= 1;
|
||||||
longestSubstringColumn -= 1;
|
longestSubstringColumn -= 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user