JavaScript最长公共子序列

时间:2020-01-27 05:26:04

标签: javascript algorithm loops

我有一个必须返回结果的算法,如下所示:

/*
"ABAZDC", "BACBAD" => ABAD
"AGGTAB", "GXTXAYB" => GTAB
"aaaa", "aa" => "aa"
"", "..." => ""
"ABBA", "ABCABA" => "ABBA"
*/

我开发的代码没有返回这些结果。我该怎么解决?

console.log(solution('ABAZDC', 'BACBAD')) 

function solution(str1, str2) {
  str1 = str1.split('')
  str2 = str2.split('')  

  const output = []

  for(let i = str1.length -1; i >= 0; i--) {   
    for(let j = str2.length -1; j >= 0; j--) {
      if( str2[j] === str1[i] ) {
        output.push(str2[j]) 
        break
      }      
    } 

  }

  return output.reverse().join('')

}

注意:

这是youtube上的解决方案。但是,对我来说,这种解决方案非常复杂。我想获得一个更简单的解决方案,其中不包含递归方法或备注,以便像迭代解决方案一样更清楚地理解。

https://www.youtube.com/watch?v=10WnvBk9sZc&feature=youtu.be

5 个答案:

答案 0 :(得分:1)

我建议您先观看此视频,其中详细介绍了该解决方案。 https://www.youtube.com/watch?v=ASoaQq66foQ

代码返回的是字符串的最大长度,您可以对其进行修改以达到您的目的。

function longestCommonSubsequence(s1, s2) {
  // string to array
  const arr1 = [...s1]
  const arr2 = [...s2]

  // define n x m sized array filled with 0's
  let matrix = [...Array(arr1.length+1)].map(e => Array(arr2.length+1).fill(0))

  // fill the matrix
  for(let i = 1; i <= arr1.length; i++) {
      for(let j = 1; j <= arr2.length; j++) {
          if(arr1[i-1] == arr2[j-1]) { matrix[i][j] = matrix[i-1][j] + 1}
          else matrix[i][j] = Math.max(matrix[i-1][j], matrix[i][j-1])
      }
  }

  // return the max which is at the right bottom corner of the matrix
  return matrix[matrix.length-1][matrix[0].length-1]
}

答案 1 :(得分:1)

该函数将返回给定两个字符串的最长子字符串。

function longestCommonSubstring(str1, str2) {

    if (str1 === str2) return str2;
    if (!str2.split('').some(ele => str1.includes(ele))) return '';
    let commonSubStr = '';
    let storage = [];
    const strLength = str2.length;

    for (let i = 0; i < strLength; i++) {

        let ind = str1.indexOf(str2[i]);
        if (ind === -1) continue;

        for (let j = i, k = ind; j < strLength; j++, k++) {
            if (str2[j] === str1[k])
                commonSubStr += str2[j];
            else {
                storage.push(commonSubStr);
                commonSubStr = '';
            }
        }
        storage.push(commonSubStr);
        commonSubStr = '';
    }

    return storage.sort((a, b) => b.length - a.length)[0].length;
}

答案 2 :(得分:0)

有关如何在两个字符串之间查找LCS的非常好的解释可以在https://alfedenzo.livejournal.com/170301.html中找到。我在针对PatienceDiff的javascript解决方案中使用了该文章,该文章位于https://github.com/jonTrent/PatienceDiff

答案 3 :(得分:0)

// the shortest way
function lcs(
s1, s2, alp=2, accumulator = ''
){
  for( let a in s1 ){
    for( let b=a-alp; b<a+alp; b++ ){
      accumulator += ( s2[b] === s1[a] && a-b < alp && b-a < alp ) ? s1[a]:"";
    }
  }
  return accumulator;
}
console.log(
lcs("ABAZDC", "BACBAD") +'\n'+ 
lcs("AGGTAB", "GXTXAYB")
);

答案 4 :(得分:-1)

您只需要添加一个检查,确定是否已经添加了与该字符匹配的字符,如! output.contains(str2[j] )或以下

    function solution(str1, str2) {
  str1 = str1.split('')
  str2 = str2.split('')  

  const output = []

  for(let i = str1.length -1; i >= 0; i--) {   
    for(let j = str2.length -1; j >= 0; j--) {
      if( str2[j] === str1[i]
          ) {
          str2.replace(str2[j], "" ) ;
        output.push(str2[j]) 
        break
      }      
    } 

  }