Skip to content

Commit

Permalink
change backtrack to be iterative
Browse files Browse the repository at this point in the history
  • Loading branch information
Arye Lukashevski committed Jun 28, 2018
1 parent 6afbbdc commit 0d54772
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 35 deletions.
68 changes: 33 additions & 35 deletions src/filters/lcs.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ reference: http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
*/

const defaultMatch = function(array1, array2, index1, index2) {
return array1[index1] === array2[index2];
return array1[ index1 ] === array2[ index2 ];
};

const lengthMatrix = function(array1, array2, match, context) {
Expand All @@ -16,56 +16,56 @@ const lengthMatrix = function(array1, array2, match, context) {
let x, y;

// initialize empty matrix of len1+1 x len2+1
let matrix = [len1 + 1];
let matrix = [ len1 + 1 ];
for (x = 0; x < len1 + 1; x++) {
matrix[x] = [len2 + 1];
matrix[ x ] = [ len2 + 1 ];
for (y = 0; y < len2 + 1; y++) {
matrix[x][y] = 0;
matrix[ x ][ y ] = 0;
}
}
matrix.match = match;
// save sequence lengths for each coordinate
for (x = 1; x < len1 + 1; x++) {
for (y = 1; y < len2 + 1; y++) {
if (match(array1, array2, x - 1, y - 1, context)) {
matrix[x][y] = matrix[x - 1][y - 1] + 1;
matrix[ x ][ y ] = matrix[ x - 1 ][ y - 1 ] + 1;
} else {
matrix[x][y] = Math.max(matrix[x - 1][y], matrix[x][y - 1]);
matrix[ x ][ y ] = Math.max(matrix[ x - 1 ][ y ], matrix[ x ][ y - 1 ]);
}
}
}
return matrix;
};

const backtrack = function(matrix, array1, array2, index1, index2, context) {
if (index1 === 0 || index2 === 0) {
return {
sequence: [],
indices1: [],
indices2: [],
};
}

if (matrix.match(array1, array2, index1 - 1, index2 - 1, context)) {
const subsequence = backtrack(
matrix,
array1,
array2,
index1 - 1,
index2 - 1,
context
);
subsequence.sequence.push(array1[index1 - 1]);
subsequence.indices1.push(index1 - 1);
subsequence.indices2.push(index2 - 1);
return subsequence;
}
const backtrack = function(matrix, array1, array2, context) {
let index1 = array1.length;
let index2 = array2.length;
const subsequence = {
sequence: [],
indices1: [],
indices2: [],
};

if (matrix[index1][index2 - 1] > matrix[index1 - 1][index2]) {
return backtrack(matrix, array1, array2, index1, index2 - 1, context);
} else {
return backtrack(matrix, array1, array2, index1 - 1, index2, context);
while (index1 !== 0 && index2 !== 0) {
const sameLetter =
matrix.match(array1, array2, index1 - 1, index2 - 1, context);
if (sameLetter) {
subsequence.sequence.unshift(array1[ index1 - 1 ]);
subsequence.indices1.unshift(index1 - 1);
subsequence.indices2.unshift(index2 - 1);
--index1;
--index2;
} else {
const valueAtMatrixAbove = matrix[ index1 ][ index2 - 1 ];
const valueAtMatrixLeft = matrix[ index1 - 1 ][ index2 ];
if (valueAtMatrixAbove > valueAtMatrixLeft) {
--index2;
} else {
--index1;
}
}
}
return subsequence;
};

const get = function(array1, array2, match, context) {
Expand All @@ -80,8 +80,6 @@ const get = function(array1, array2, match, context) {
matrix,
array1,
array2,
array1.length,
array2.length,
innerContext
);
if (typeof array1 === 'string' && typeof array2 === 'string') {
Expand Down
17 changes: 17 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,4 +751,21 @@ describe('lcs', () => {
indices2: [1],
});
});

it('should compute diff for large array', () => {
const ARRAY_LENGTH = 5000; // js stack is about 50k
function randomArray() {
let result = [];
for (let i = 0; i < ARRAY_LENGTH; i++) {
if (Math.random() > 0.5) {
result.push('A');
} else {
result.push('B');
}
}
return result;
}

lcs.get(randomArray(), randomArray());
});
});

0 comments on commit 0d54772

Please # to comment.