Skip to content

Instantly share code, notes, and snippets.

@tecteun
Created October 23, 2020 11:53
Show Gist options
  • Save tecteun/3dc9f54ace2cca6d0ee12be4fd2e14c4 to your computer and use it in GitHub Desktop.
Save tecteun/3dc9f54ace2cca6d0ee12be4fd2e14c4 to your computer and use it in GitHub Desktop.
levenshtein distance
// https://en.wikipedia.org/wiki/Levenshtein_distance
function lv(A, B) {
// create two work vectors of integer distances
let v0 = new Array(A.length);
let v1 = new Array(B.length);
// initialize v0 (the previous row of distances)
// this row is A[0][i]: edit distance for an empty s
// the distance is just the number of characters to delete from t
for(let i = 0; i <= B.length + 1; i++){
v0[i] = i;
}
for(let i = 0; i < A.length + 1; i++){
// calculate v1 (current row distances) from the previous row v0
// first element of v1 is A[i+1][0]
// edit distance is delete (i+1) chars from s to match empty t
v1[0] = i + 1
// use formula to fill in the rest of the row
for(let j = 0; j < B.length + 1; j++){
// calculating costs for A[i+1][j+1]
let deletionCost = v0[j + 1] + 1 || 0;
let insertionCost = v1[j] + 1;
let substitutionCost = A[i] === B[j] ? v0[j] : v0[j] + 1 || 0;
v1[j + 1] = Math.min(deletionCost, insertionCost, substitutionCost)
}
// copy v1 (current row) to v0 (previous row) for next iteration
// since data in v1 is always invalidated, a swap without copy could be more efficient
let temp = v0;
v0 = v1.concat([]);
v1 = temp.concat([]);
}
// after the last swap, the results of v1 are now in v0
return v0[B.length + 1];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment