| 1 | // TheSpanishInquisition
|
|---|
| 2 |
|
|---|
| 3 | // Cache the matrix. Note that if you not pass a limit this implementation will use a dynamically calculate one.
|
|---|
| 4 |
|
|---|
| 5 | module.exports = function(__this, that, limit) {
|
|---|
| 6 |
|
|---|
| 7 | var thisLength = __this.length,
|
|---|
| 8 | thatLength = that.length,
|
|---|
| 9 | matrix = [];
|
|---|
| 10 |
|
|---|
| 11 | // If the limit is not defined it will be calculate from this and that args.
|
|---|
| 12 | limit = (limit || ((thatLength > thisLength ? thatLength : thisLength)))+1;
|
|---|
| 13 |
|
|---|
| 14 | for (var i = 0; i < limit; i++) {
|
|---|
| 15 | matrix[i] = [i];
|
|---|
| 16 | matrix[i].length = limit;
|
|---|
| 17 | }
|
|---|
| 18 | for (i = 0; i < limit; i++) {
|
|---|
| 19 | matrix[0][i] = i;
|
|---|
| 20 | }
|
|---|
| 21 |
|
|---|
| 22 | if (Math.abs(thisLength - thatLength) > (limit || 100)){
|
|---|
| 23 | return prepare (limit || 100);
|
|---|
| 24 | }
|
|---|
| 25 | if (thisLength === 0){
|
|---|
| 26 | return prepare (thatLength);
|
|---|
| 27 | }
|
|---|
| 28 | if (thatLength === 0){
|
|---|
| 29 | return prepare (thisLength);
|
|---|
| 30 | }
|
|---|
| 31 |
|
|---|
| 32 | // Calculate matrix.
|
|---|
| 33 | var j, this_i, that_j, cost, min, t;
|
|---|
| 34 | for (i = 1; i <= thisLength; ++i) {
|
|---|
| 35 | this_i = __this[i-1];
|
|---|
| 36 |
|
|---|
| 37 | // Step 4
|
|---|
| 38 | for (j = 1; j <= thatLength; ++j) {
|
|---|
| 39 | // Check the jagged ld total so far
|
|---|
| 40 | if (i === j && matrix[i][j] > 4) return prepare (thisLength);
|
|---|
| 41 |
|
|---|
| 42 | that_j = that[j-1];
|
|---|
| 43 | cost = (this_i === that_j) ? 0 : 1; // Step 5
|
|---|
| 44 | // Calculate the minimum (much faster than Math.min(...)).
|
|---|
| 45 | min = matrix[i - 1][j ] + 1; // Deletion.
|
|---|
| 46 | if ((t = matrix[i ][j - 1] + 1 ) < min) min = t; // Insertion.
|
|---|
| 47 | if ((t = matrix[i - 1][j - 1] + cost) < min) min = t; // Substitution.
|
|---|
| 48 |
|
|---|
| 49 | // Update matrix.
|
|---|
| 50 | matrix[i][j] = (i > 1 && j > 1 && this_i === that[j-2] && __this[i-2] === that_j && (t = matrix[i-2][j-2]+cost) < min) ? t : min; // Transposition.
|
|---|
| 51 | }
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | return prepare (matrix[thisLength][thatLength]);
|
|---|
| 55 |
|
|---|
| 56 | /**
|
|---|
| 57 | *
|
|---|
| 58 | */
|
|---|
| 59 | function prepare(steps) {
|
|---|
| 60 | var length = Math.max(thisLength, thatLength)
|
|---|
| 61 | var relative = length === 0
|
|---|
| 62 | ? 0
|
|---|
| 63 | : (steps / length);
|
|---|
| 64 | var similarity = 1 - relative
|
|---|
| 65 | return {
|
|---|
| 66 | steps: steps,
|
|---|
| 67 | relative: relative,
|
|---|
| 68 | similarity: similarity
|
|---|
| 69 | };
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | };
|
|---|