Skip to content

Commit af64d12

Browse files
committedAug 28, 2018
Add more unicode related tests to longestCommonSubstring algorithm.
1 parent 82ac89b commit af64d12

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed
 

‎src/algorithms/string/longest-common-substring/__test__/longestCommonSubstring.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ describe('longestCommonSubstring', () => {
77
expect(longestCommonSubstring('', 'ABC')).toBe('');
88
expect(longestCommonSubstring('ABABC', 'BABCA')).toBe('BABC');
99
expect(longestCommonSubstring('BABCA', 'ABCBA')).toBe('ABC');
10+
expect(longestCommonSubstring(
11+
'Algorithms and data structures implemented in JavaScript',
12+
'Here you may find Algorithms and data structures that are implemented in JavaScript',
13+
)).toBe('Algorithms and data structures ');
14+
});
15+
16+
it('should handle unicode correctly', () => {
1017
expect(longestCommonSubstring('𐌵𐌵**ABC', '𐌵𐌵--ABC')).toBe('ABC');
18+
expect(longestCommonSubstring('𐌵𐌵**A', '𐌵𐌵--A')).toBe('𐌵𐌵');
19+
expect(longestCommonSubstring('A买B时', '买B时GD')).toBe('买B时');
20+
expect(longestCommonSubstring('After test买时 case', 'another_test买时')).toBe('test买时');
1121
});
1222
});

‎src/algorithms/string/longest-common-substring/longestCommonSubstring.js

+17-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
/**
2-
* @param {string} s1
3-
* @param {string} s2
2+
* @param {string} string1
3+
* @param {string} string2
44
* @return {string}
55
*/
6-
export default function longestCommonSubstring(s1, s2) {
7-
// transform s1 & s2 into arrays to allow handling unicodes as single caracter.
8-
const [a1, a2] = [s1, s2].map(s => Array.from(s));
6+
export default function longestCommonSubstring(string1, string2) {
7+
// Convert strings to arrays to treat unicode symbols length correctly.
8+
// For example:
9+
// '𐌵'.length === 2
10+
// [...'𐌵'].length === 1
11+
const s1 = [...string1];
12+
const s2 = [...string2];
913

1014
// Init the matrix of all substring lengths to use Dynamic Programming approach.
11-
const substringMatrix = Array(a2.length + 1).fill(null).map(() => {
12-
return Array(a1.length + 1).fill(null);
15+
const substringMatrix = Array(s2.length + 1).fill(null).map(() => {
16+
return Array(s1.length + 1).fill(null);
1317
});
1418

1519
// Fill the first row and first column with zeros to provide initial values.
16-
for (let columnIndex = 0; columnIndex <= a1.length; columnIndex += 1) {
20+
for (let columnIndex = 0; columnIndex <= s1.length; columnIndex += 1) {
1721
substringMatrix[0][columnIndex] = 0;
1822
}
1923

20-
for (let rowIndex = 0; rowIndex <= a2.length; rowIndex += 1) {
24+
for (let rowIndex = 0; rowIndex <= s2.length; rowIndex += 1) {
2125
substringMatrix[rowIndex][0] = 0;
2226
}
2327

@@ -26,9 +30,9 @@ export default function longestCommonSubstring(s1, s2) {
2630
let longestSubstringColumn = 0;
2731
let longestSubstringRow = 0;
2832

29-
for (let rowIndex = 1; rowIndex <= a2.length; rowIndex += 1) {
30-
for (let columnIndex = 1; columnIndex <= a1.length; columnIndex += 1) {
31-
if (a1[columnIndex - 1] === a2[rowIndex - 1]) {
33+
for (let rowIndex = 1; rowIndex <= s2.length; rowIndex += 1) {
34+
for (let columnIndex = 1; columnIndex <= s1.length; columnIndex += 1) {
35+
if (s1[columnIndex - 1] === s2[rowIndex - 1]) {
3236
substringMatrix[rowIndex][columnIndex] = substringMatrix[rowIndex - 1][columnIndex - 1] + 1;
3337
} else {
3438
substringMatrix[rowIndex][columnIndex] = 0;
@@ -53,7 +57,7 @@ export default function longestCommonSubstring(s1, s2) {
5357
let longestSubstring = '';
5458

5559
while (substringMatrix[longestSubstringRow][longestSubstringColumn] > 0) {
56-
longestSubstring = a1[longestSubstringColumn - 1] + longestSubstring;
60+
longestSubstring = s1[longestSubstringColumn - 1] + longestSubstring;
5761
longestSubstringRow -= 1;
5862
longestSubstringColumn -= 1;
5963
}

0 commit comments

Comments
 (0)
Please sign in to comment.