Skip to content

Commit 8dd0c14

Browse files
committedApr 24, 2018
Add Levenshtein.
1 parent 075fe39 commit 8dd0c14

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import levenshteinDistance from '../levenshteinDistance';
2+
3+
describe('levenshteinDistance', () => {
4+
it('should calculate edit distance between two strings', () => {
5+
expect(levenshteinDistance('', '')).toBe(0);
6+
expect(levenshteinDistance('a', '')).toBe(1);
7+
expect(levenshteinDistance('', 'a')).toBe(1);
8+
expect(levenshteinDistance('abc', '')).toBe(3);
9+
expect(levenshteinDistance('', 'abc')).toBe(3);
10+
11+
// Should just add I to the beginning.
12+
expect(levenshteinDistance('islander', 'slander')).toBe(1);
13+
14+
// Needs to substitute M by K, T by M and add an A to the end
15+
expect(levenshteinDistance('mart', 'karma')).toBe(3);
16+
17+
// Substitute K by S, E by I and insert G at the end.
18+
expect(levenshteinDistance('kitten', 'sitting')).toBe(3);
19+
20+
// Should add 4 letters FOOT at the beginning.
21+
expect(levenshteinDistance('ball', 'football')).toBe(4);
22+
23+
// Should delete 4 letters FOOT at the beginning.
24+
expect(levenshteinDistance('football', 'foot')).toBe(4);
25+
26+
// Needs to substitute the first 5 chars: INTEN by EXECU
27+
expect(levenshteinDistance('intention', 'execution')).toBe(5);
28+
});
29+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @param {string} a
3+
* @param {string} b
4+
* @return {number}
5+
*/
6+
export default function levenshteinDistance(a, b) {
7+
// Create empty edit distance matrix for all possible modifications of
8+
// substrings of a to substrings of b.
9+
const distanceMatrix = Array(b.length + 1).fill(null).map(() => Array(a.length + 1).fill(null));
10+
11+
// Fill the first raw of the matrix.
12+
// If this is first row then we're transforming empty string to a.
13+
// In this case the number of transformations equals to size of a substring.
14+
for (let i = 0; i <= a.length; i += 1) {
15+
distanceMatrix[0][i] = i;
16+
}
17+
18+
// Fill the first column of the matrix.
19+
// If this is first column then we're transforming empty string to b.
20+
// In this case the number of transformations equals to size of b substring.
21+
for (let j = 0; j <= b.length; j += 1) {
22+
distanceMatrix[j][0] = j;
23+
}
24+
25+
for (let j = 1; j <= b.length; j += 1) {
26+
for (let i = 1; i <= a.length; i += 1) {
27+
const indicator = a[i - 1] === b[j - 1] ? 0 : 1;
28+
distanceMatrix[j][i] = Math.min(
29+
distanceMatrix[j][i - 1] + 1, // deletion
30+
distanceMatrix[j - 1][i] + 1, // insertion
31+
distanceMatrix[j - 1][i - 1] + indicator, // substitution
32+
);
33+
}
34+
}
35+
36+
return distanceMatrix[b.length][a.length];
37+
}

0 commit comments

Comments
 (0)
Please sign in to comment.