87 lines
2.6 KiB
JavaScript
87 lines
2.6 KiB
JavaScript
|
(function (exports) {
|
||
|
'use strict';
|
||
|
|
||
|
exports.longestCommonSubsequence = (function () {
|
||
|
|
||
|
/**
|
||
|
* Find the lengths of longest common sub-sequences
|
||
|
* of two strings and their substrings.
|
||
|
*
|
||
|
* Complexity: O(MN).
|
||
|
*
|
||
|
* @private
|
||
|
* @param {String} first string
|
||
|
* @param {String} second string
|
||
|
* @return {Array} two dimensional array with LCS
|
||
|
* lengths of input strings and their substrings.
|
||
|
*
|
||
|
*/
|
||
|
function getLcsLengths(str1, str2) {
|
||
|
var result = [];
|
||
|
for (var i = -1; i < str1.length; i = i + 1) {
|
||
|
result[i] = [];
|
||
|
for (var j = -1; j < str2.length; j = j + 1) {
|
||
|
if (i === -1 || j === -1) {
|
||
|
result[i][j] = 0;
|
||
|
} else if (str1[i] === str2[j]) {
|
||
|
result[i][j] = result[i - 1][j - 1] + 1;
|
||
|
} else {
|
||
|
result[i][j] = Math.max(result[i - 1][j], result[i][j - 1]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Find longest common sub-sequences of two strings.
|
||
|
*
|
||
|
* Complexity: O(M + N).
|
||
|
*
|
||
|
* @private
|
||
|
* @param {String} first string
|
||
|
* @param {String} second string
|
||
|
* @return {Array} two dimensional array with LCS
|
||
|
* lengths of input strings and their substrings
|
||
|
* returned from 'getLcsLengths' function.
|
||
|
*
|
||
|
*/
|
||
|
function getLcs(str1, str2, lcsLengthsMatrix) {
|
||
|
var execute = function (i, j) {
|
||
|
if (!lcsLengthsMatrix[i][j]) {
|
||
|
return '';
|
||
|
} else if (str1[i] === str2[j]) {
|
||
|
return execute(i - 1, j - 1) + str1[i];
|
||
|
} else if (lcsLengthsMatrix[i][j - 1] > lcsLengthsMatrix[i - 1][j]) {
|
||
|
return execute(i, j - 1);
|
||
|
} else {
|
||
|
return execute(i - 1, j);
|
||
|
}
|
||
|
};
|
||
|
return execute(str1.length - 1, str2.length - 1);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Algorithm from dynamic programming. It finds the longest
|
||
|
* common sub-sequence of two strings. For example for strings 'abcd'
|
||
|
* and 'axxcda' the longest common sub-sequence is 'acd'.
|
||
|
*
|
||
|
* @example
|
||
|
* var subsequence = require('path-to-algorithms/src/searching/'+
|
||
|
* 'longest-common-subsequence').longestCommonSubsequence;
|
||
|
* console.log(subsequence('abcd', 'axxcda'); // 'acd'
|
||
|
*
|
||
|
* @public
|
||
|
* @module searching/longest-common-subsequence
|
||
|
* @param {String} first input string.
|
||
|
* @param {String} second input string.
|
||
|
* @return {Array} Longest common subsequence.
|
||
|
*/
|
||
|
return function (str1, str2) {
|
||
|
var lcsLengthsMatrix = getLcsLengths(str1, str2);
|
||
|
return getLcs(str1, str2, lcsLengthsMatrix);
|
||
|
};
|
||
|
})();
|
||
|
|
||
|
})(typeof window === 'undefined' ? module.exports : window);
|