【问题标题】:How to write a function that returns true if a portion of str1 can be rearranged to str2?如果 str1 的一部分可以重新排列为 str2,如何编写一个返回 true 的函数?
【发布时间】:2017-04-10 22:06:23
【问题描述】:

我在以下问题上遇到问题。如果 str1 的一部分可以重新排列为 str2,我基本上必须编写一个返回 true 的代码/函数。

编写函数 scramble(str1,str2),如果 str1 字符的一部分可以重新排列以匹配 str2,则返回 true,否则返回 false。

例如: str1 是 'rkqodlw' 而 str2 是 'world' 输出应该返回 true。 str1 是 'cedewaraaossoqqyt' 而 str2 是 'codewars' 应该返回 true。 str1 是 'katas' 而 str2 是 'steak' 应该返回 false。

仅使用小写字母 (a-z)。不包含标点符号或数字。 需要考虑性能。

下面是我目前的代码:

function scramble(str1, str2) {
  var first; //longer string
  var second; //shorter string

  if(str1 || str2 === "undefined") {
    return false;
  }

  if(str1.length > str2.length) {
    first = str1;
    second = str2
  } else if(str2.length > str1.length) {
    first = str2;
    second = str1;
  }

  for (i=0; i<second.length; i++) {
    if (first.indexOf(second[i]) === -1) {
      return false;
    }
  }

  return true;

}

你能帮我解决这个问题吗?

【问题讨论】:

  • 我一头雾水,不就是检查str2中的所有字符是否都在str1中那么简单吗,如果是,则返回true?
  • 另外,if(str1 || str2 === "undefined") { 并没有像你想象的那样做

标签: javascript function recursion scramble


【解决方案1】:

将字符串拆分为数组,并检查第二个数组中的每个字符是否都在第一个数组内。

你可能想在你去的时候拼接字符,以解释同一个字符的多个

function scramble(str1, str2) {
    var [arr1, arr2] = [str1.split(''), str2.split('')];
    return arr2.every(x=>arr1.indexOf(x)===-1?false:arr1.splice(arr1.indexOf(x),1));
}

console.log( scramble('rkqwodlw', 'world') );     // true
console.log( scramble('mgoaon', 'moon') );        // true
console.log( scramble('oijhnnassduda', 'moon') ); // false, only one "o"
console.log( scramble('test', 'unicorn') );       // false

【讨论】:

    【解决方案2】:

    这是带有一些测试的函数:

    function scramble(str1, str2) {
      var l = str2.length;
      for (var i = 0; i < l; i++) {
        if (str1.indexOf(str2[i]) > -1) {
          str1 = str1.replace(str2[i], '');
        } else {
          return false;
        }
      }
      return true;
    }
    
    function test(str1, str2) {
      console.log('testing "'+str1+'" w/ "'+str2+'": '+(scramble(str1, str2) ? 'true' : 'false'));
    }
    
    test('rkqodlw', 'world');
    test('cedewaraaossoqqyt', 'codewars');
    test('katas', 'steak');

    测试正在返回:

    testing "rkqodlw" w/ "world": true
    testing "cedewaraaossoqqyt" w/ "codewars": true
    testing "katas" w/ "steak": false
    

    该函数检查 str2 的每个 char 是否都在 str1 中并将其从 str1 中删除,以便 str1 中的 char 不计算两次。

    【讨论】:

      【解决方案3】:

      您可以使用哈希表来计算字母的数量,然后使用 count 检查并减少计数。

      这个提议不会改变数组。

      function scramble(str1, str2) {
          var count = Object.create(null);
      
          Array.prototype.forEach.call(str1, function(a) {
              count[a] = (count[a] || 0) + 1;
          });
      
          return Array.prototype.every.call(str2, function(a) {
              return count[a]--;
          });
      }
      
      console.log(scramble('rkqodlw', 'world'));              // true
      console.log(scramble('cedewaraaossoqqyt', 'codewars')); // true
      console.log(scramble('katas', 'steak'));                // false
      console.log(scramble('', 'o'));                // false

      【讨论】:

      • 比其他解决方案更难理解,但时间复杂度更高。
      • 不确定,但您必须迭代并创建地图,而且它并不总是比使用 indexOf 等内置函数查找值更快
      • 但是为什么拼接速度更快?
      【解决方案4】:
      function scramble(str1, str2) {
      var [a,b,c] = [str1.split(''),str2.split(''),[]];
      for (let i = 0; i < b.length; i++) {
          if (a.indexOf(b[i]) !== -1) {c.push(b[i]), a.splice(a.indexOf(b[i]), 1);}
      }
      return b.join('') === c.join('');}
      

      【讨论】:

      • 如果你能提供示例输入和输出会更好,所以我们不需要猜测这段代码在做什么。
      • 请不要只发布代码作为答案,还要说明您的代码的作用以及它如何解决问题的问题。带有解释的答案通常质量更高,更有可能吸引投票
      • 虽然这可能会回答问题,但它已被标记为待审核。没有解释的答案通常被认为是低质量的。请在答案中提供一些评论,说明为什么这是正确答案。
      猜你喜欢
      • 2021-08-23
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2011-09-11
      相关资源
      最近更新 更多