如何获得两个字符串中的公共子字符串以维持顺序?

时间:2018-07-17 07:35:21

标签: javascript html

我正在尝试解决hackerrank的一个问题,但无法解决该问题

有人可以帮我完成我错误的逻辑实现吗?

问题

打印最长字符串的长度,以便它是s1和s2的子代。

样本输入

HARRY
SALLY

样本输出

 2

说明

通过从HARRY和SALLY中删除零个或多个字符可以形成的最长字符串是AY,其长度为2。

样本输入1

AA
BB

样本输出1

0

说明1

AA和BB没有共同的字符,因此输出为0

样本输入2

SHINCHAN
NOHARAAA

样本输出2

3

说明2

在保持顺序的同时,SHINCHAN和NOHARAAA之间可以形成的最长字符串是NHA。

我写了一些逻辑,如下:

 

   function commonChild(s1, s2) {

    var arr = s2.split(),
        currenString = '',
        maxLength = 0,
        index = -1;
  console.log(arr);

    for (var i = 0; i < s1.length; i++) {
        var char = s1.charAt(i),
            charIndex = arr.indexOf(char);
        console.log(char)
        if (index < charIndex) {
            index = charIndex;
            currenString +=char;
        }

        maxLength= Math.max(maxLength,currenString.length)
    }

    return maxLength;

}


commonChild('ABCDEF', 'FBDAMN');


console.log(commonChild('ABCDEF', 'FBDAMN'));

5 个答案:

答案 0 :(得分:1)

请原谅我。这是未优化的解决方案。

function maxCommon(a, b, offset) {
  offset = offset || 0;

  if (a === b) {
    return [[a, b]];
  }
  var possibleSolns = [];
  for (var i = 0 + offset; i < a.length; i++) {
    for (var j = 0 + offset; j < b.length; j++) {
      if (a.charAt(i) === b.charAt(j)) {
        possibleSolns.push([
          a.substring(0, offset) + a.substring(i),
          b.substring(0, offset) +b.substring(j)
        ]);
        break;
      }
    }
  }

  var results = [];
  possibleSolns.forEach(function(soln) {
    var s = maxCommon(soln[0], soln[1], offset+1);
    if (s.length === 0) {
      s = [[soln[0].substring(0, offset +1), soln[1].substring(0, offset +1)]];
    }
    results = results.concat(s);
  });
  return results;
}

var maxLen = -1;
var soln = null;
maxCommon("ABCDEF", "FBDAMN").map(function(_) {
  return _[0];
}).forEach(function(_) {
  if (_.length > maxLen) {
    soln = _;
    maxLen = _.length;
  }
});

console.log(soln);

答案 1 :(得分:0)

使用lodash和传播操作可以通过这种方式完成。

const test = (first, second) => {
  const stringArray1 = [...first];
  const stringArray2 = [...second];
  return _.intersection(stringArray1, stringArray2).length;
}

console.log(test('ABCDEF', 'FBDAMN'));

答案 2 :(得分:0)

您可以使用lcs最小公共子序列来解决

function LCS(s1,s2,x,y){
    var result = 0;
    if(x==0 || y==0){
        result = 0
    }else if(s1[x-1] == s2[y-1]){
        result = 1+ LCS(s1,s2,x-1,y-1)
    } else if(s1[x-1] != s2[y-1]){
        result = Math.max(LCS(s1,s2,x-1,y), LCS(s1,s2,x,y-1))
    }
    return result;
}



// Complete the commonChild function below.
function commonChild(s1, s2) {

    return LCS(s1,s2,s1.length,s2.length);

}

答案 3 :(得分:-1)

根据您编辑之前的代码。 一个小的更改是将var arr = s2.split()更改为split('')。 逻辑上的主要变化是,我添加了一个循环,以便每次从另一个字符遍历字符串时(第一个循环从第一个循环开始,第二个循环从第二个循环开始,依次类推)。

function commonChild(s1, s2) {
  var arr = s2.split(''),
    currenString = '',
    maxLength = 0,
    index = -1,
    j = -1;
  for (var ii = 0; ii < s1.length; ii++) {
    index = -1;
    currenString = '';
    for (var i = ii; i < s1.length; i++) {
      var char = s1.charAt(i),
        j = arr.indexOf(char);
      if (index < j) {
        index = j;
        currenString += char;
      }
      maxLength = Math.max(maxLength, currenString.length)
    }
  }
  return maxLength;
}
console.log(commonChild('ABCDEF', 'FBDAMN'));

答案 4 :(得分:-1)

我在回答中保留了您的大多数逻辑:

function commonChild(s1, s2) {
  var // Sets strings to arrays
    arrayString1 = s1.split(""),
    arrayString2 = s2.split(""),
    collectedChars = "",
    maxLength = 0,
    max = arrayString1.length;
  

  for (var i = 0; i < max; i++) {
    var
      char = arrayString1[i],
      count = arrayString2.indexOf(char);
     
    // check if char is in second string and not in collected
    if (count != -1 && collectedChars.indexOf(char) == -1) {
      collectedChars += char;
      maxLength++;
    }
  }

  return maxLength;
}

// expected output 4
console.log(commonChild(
                'ABCDEF',
                'FBDAMN'
            ));

// expected output 1
console.log(commonChild(
                'AA',
                'FBDAMN'
            ));