Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a88c0b9

Browse files
committed
Merge pull request mgechev#87 from deniskyashif/levenshtein-distance-tuning-and-tests
Optimized Levenshtein distance algorithm and added unit tests.
2 parents 766c111 + 9f2c410 commit a88c0b9

File tree

2 files changed

+82
-14
lines changed

2 files changed

+82
-14
lines changed

src/others/levenshtein-distance.js

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,31 @@
33

44
var levenshteinDistance = (function () {
55

6-
function levenshteinDistance(s, ls, t, lt) {
7-
if (ls === 0) {
8-
return lt;
9-
}
10-
if (lt === 0) {
11-
return ls;
6+
function levenshteinDistance (s, ls, t, lt) {
7+
var memo = [];
8+
var currRowMemo;
9+
var i;
10+
var k;
11+
12+
for (k = 0; k <= lt; k += 1) {
13+
memo[k] = k;
1214
}
13-
var cost;
14-
if (s[ls - 1] === t[lt - 1]) {
15-
cost = 0;
16-
} else {
17-
cost = 1;
15+
16+
for (i = 1; i <= ls; i += 1) {
17+
currRowMemo = [i];
18+
19+
for (k = 1; k <= lt; k += 1) {
20+
currRowMemo[k] = Math.min(
21+
currRowMemo[k - 1] + 1,
22+
memo[k] + 1,
23+
memo[k - 1] + (s[i - 1] !== t[k - 1] ? 1 : 0)
24+
);
25+
}
26+
27+
memo = currRowMemo;
1828
}
19-
return Math.min(levenshteinDistance(s, ls - 1, t, lt) + 1,
20-
levenshteinDistance(s, ls, t, lt - 1) + 1,
21-
levenshteinDistance(s, ls - 1, t, lt - 1) + cost);
29+
30+
return memo[lt];
2231
}
2332

2433
/**
@@ -49,3 +58,4 @@
4958
exports.levenshteinDistance = levenshteinDistance;
5059

5160
}(typeof exports === 'undefined' ? window : exports));
61+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
var mod = require('../../src/others/levenshtein-distance.js');
4+
var levenshteinDistance = mod.levenshteinDistance;
5+
6+
describe('Levenstein\'s minimum edit distance algorithm', function () {
7+
it('should be defined', function () {
8+
expect(levenshteinDistance).toBeDefined();
9+
});
10+
11+
it('"" -> "" should return 0.', function () {
12+
expect(levenshteinDistance('', '')).toBe(0);
13+
});
14+
15+
it('"T" -> "" should return 1.', function () {
16+
expect(levenshteinDistance('T', '')).toBe(1);
17+
});
18+
19+
it('"cake" -> "rake" should return 1.', function () {
20+
expect(levenshteinDistance('cake', 'rake')).toBe(1);
21+
});
22+
23+
it('"Sofia" -> "Sof" should return 2.', function () {
24+
expect(levenshteinDistance('Sofia', 'Sof')).toBe(2);
25+
});
26+
27+
it('"kitten" -> "sitting" should return 3', function () {
28+
expect(levenshteinDistance('kitten', 'sitting')).toBe(3);
29+
});
30+
31+
it('"google" -> "lookat" should return 4.', function () {
32+
expect(levenshteinDistance('google', 'lookat')).toBe(4);
33+
});
34+
35+
it('"emacs" -> "vim" should return 5.', function () {
36+
expect(levenshteinDistance('emacs', 'vim')).toBe(5);
37+
});
38+
39+
it('"coffee" -> "cocoa" should return 4.', function () {
40+
expect(levenshteinDistance('coffee', 'cocoa')).toBe(4);
41+
});
42+
43+
it('"Munich" -> "Muenchen" should return 4.', function () {
44+
expect(levenshteinDistance('Munich', 'Muenchen')).toBe(4);
45+
});
46+
47+
it('"rosebud" -> "budrose" should return 6.', function () {
48+
expect(levenshteinDistance('rosebud', 'budrose')).toBe(6);
49+
});
50+
51+
it('"decided" -> "decisive" should return 4.', function () {
52+
expect(levenshteinDistance('decided', 'decisive')).toBe(4);
53+
});
54+
55+
it('"similar" -> "simile" should return 2.', function () {
56+
expect(levenshteinDistance('similar', 'simile')).toBe(2);
57+
});
58+
});

0 commit comments

Comments
 (0)