diff --git a/src/algorithms/string/Longest_Common_Subsequence.js b/src/algorithms/string/Longest_Common_Subsequence.js new file mode 100644 index 00000000..e3768040 --- /dev/null +++ b/src/algorithms/string/Longest_Common_Subsequence.js @@ -0,0 +1,43 @@ + +const Longest_Common_Subsequence = (arr1, arr2) => { + + let LCS_def = Array.from({ length: arr1.length + 1 }, + () => Array.from({ length: arr2.length + 1 }, + () => 0)); + + for (let i = 0; i < arr1.length + 1; i++){ + for (let j = 0; j < arr2.length+1; j++){ + + if (i == 0 || j == 0) { + LCS_def[i][j] = 0; + } + + // when the last character of both match, increase length of lcs by 1 + else if (arr1[i - 1] == arr2[j - 1]) { + LCS_def[i][j] = LCS_def[i - 1][j - 1] + 1; + } + + /* + when the last character is not same, take maximum obtained by adding + one character to one of the subsequences. + */ + else { + LCS_def[i][j] = Math.max(LCS_def[i - 1][j], LCS_def[i][j - 1]) + } + } + } + + return `The length of longest subsequence is: ${LCS_def[arr1.length][arr2.length]}`; + +} + + module.exports = Longest_Common_Subsequence; + +// I/P and O/P Examples + +const inputSet1 = [10, 15, 20, 25, 30, 35, 40]; +const inputSet2 = [10, 12, 23, 25, 28, 30, 32, 40]; +const result = Longest_Common_Subsequence(inputSet1, inputSet2); + +// The length of longest subsequence is: 4 +console.log(result); diff --git a/src/algorithms/string/Rabin_karp.js b/src/algorithms/string/Rabin_karp.js new file mode 100644 index 00000000..1611699f --- /dev/null +++ b/src/algorithms/string/Rabin_karp.js @@ -0,0 +1,43 @@ +const rabinKarp = (pat, str) => { + let p = 31 + let m = 1000000007 + let S = pat.length + let T = str.length + + let p_pow = [] // precomputing powers of p mod m + p_pow.push(1) // p^0 = 1 + for (let i = 1; i < Math.max(S, T); i++) { + p_pow.push((p_pow[i - 1] * p) % m); + } + + let h = [] // length-wise hash i.e h[i] = hash of the prefix with i characters + h.push(0); // h[0] = 0 + for (let i = 0; i < T; i++) { + h.push((h[i] + (str[i].charCodeAt(0) - 97 + 1) * p_pow[i]) % m); + } + + let h_s = 0; // hash value of the pattern + for (let i = 0; i < S; i++) + h_s = (h_s + (pat[i].charCodeAt(0) - 97 + 1) * p_pow[i]) % m; + + let occurs = []; // desired array storing the indices of given string where pattern occurs + for (let i = 0; i + S - 1 < T; i++) { + // slide a window of length S of the pattern + let cur_h = (h[i + S] - h[i] + m) % m; + // if current_hash matches with the hash of out pattern, then a match is found at this index + if (cur_h == h_s * p_pow[i] % m) + occurs.push(i); + } + + return occurs; +} + +// Calling the function +let str = "girlscriptsummerofcodewithgirlsandboys" +let pat = "girl" + +let ids = rabinKarp(pat, str) // desired array storing the indices of given string where pattern occurs +console.log("Pattern found at indexes: ", ids) +module.export = rabinKarp; +// Output +// Pattern found at indexes: [ 0, 26 ] diff --git a/src/algorithms/string/index.js b/src/algorithms/string/index.js index ad535890..0c50bfda 100644 --- a/src/algorithms/string/index.js +++ b/src/algorithms/string/index.js @@ -1,5 +1,9 @@ const levenshteindistance = require('./levenshtein_distance'); +const Longest_Common_Subsequence = require('./Longest_Common_Subsequence'); +const rabinKarp = require('./Rabin_karp'); module.exports = { - levenshteindistance + levenshteindistance, + Longest_Common_Subsequence, + rabinKarp, };