【问题标题】:How do I skip a comparison between two of the same arrays index?如何跳过两个相同数组索引之间的比较?
【发布时间】:2017-10-09 21:43:36
【问题描述】:

我正在做这个非常简单的codewars kata 下面是问题:

等值线是一个没有重复字母、连续或 非连续的。实现一个判断字符串是否为 只包含字母的是等值线。假设空字符串是 等值线。忽略字母大小写。

function isIsogram(str){
  var letter = str.toLowerCase().split("");

  for(var i = 0; i < letter.length; i++) {
    if(letter.indexOf(letter[i].toLowerCase()) > -1){
      return false;
    }
  }
  return true; 
}

我的解决方案总是返回 false,因为我在 indexOf 中的数组比较了我的字符串中的每个字母。该解决方案应该将数组与自身进行比较,如果没有重复的字母则返回 true。但不幸的是,当我将数组与自身进行比较时,它将比较数组中的每个字母,所以基本上即使数组中只有一个字符的字母,因为它再次与自身进行比较,它将返回一个错误的陈述。

这个问题要了我的命。

【问题讨论】:

  • 在您的 if 语句中,您能否添加类似 &amp;&amp; letter.indexOf(letter[i].toLowerCase()) !== i 的内容?
  • 您最好先对字符串进行排序,然后遍历它并将当前字母与下一个字母进行比较。您的算法被认为很慢。

标签: javascript html css arrays data-structures


【解决方案1】:

检查Array#lastIndexOf(从末尾开始搜索)是否与当前索引相同。如果不是,它不是唯一的:

function isIsogram(str){
  var letter = str.toLowerCase().split("");

  for(var i = 0; i < letter.length; i++) {
    if(letter.lastIndexOf(letter[i]) !== i){
      return false;
    }
  }
  return true; 
}

console.log(isIsogram('subdermatoglyphic'));
console.log(isIsogram('rare'));

更好的解决方案是比较使用Set 的唯一字符数与原始字符串中的字符数:

const isIsogram = (str) => new Set(str.toLowerCase()).size === str.length;

console.log(isIsogram('subdermatoglyphic'));
console.log(isIsogram('rare'));

【讨论】:

  • 使用 indexOf 和 lastIndexOf 没有区别,只是速度更快。
  • 区别在于用法上:可以用lastIndexOf(),和当前索引比较,或者indexOf()加上起始位置,判断结果是否为-1。跨度>
  • 我刚刚将我的&gt; -1 更改为!== i,这基本上解决了我的问题。这很有意义,因为在获取该字母的索引时,如果它不等于它的索引,即使它不等于它,它也会返回 false!我喜欢这个逻辑!谢谢!
  • 欢迎 :) 如果你使用 indexOf() 这个逻辑,并且没有开始索引,它只会在到达字母的第二次出现时失败。这就是我使用lastIndexOf() 的原因。
【解决方案2】:

更简单:

check = str => new Set( str.toLowerCase() ).size === str.length;

或者如果你想修复你的代码,使用两个循环:

for(var i = 0; i < letter.length; i++) {
  for(var j = i+1; j < letter.length; j++){
    if(letter[i] === letter[j]) return false;
  }
}

【讨论】:

    【解决方案3】:
    function isIsogram(str){
      var letter = str.toLowerCase().split("");
    
      for(var i = 0; i < letter.length; i++) {
        for (var y = i + 1; y < letter.length; y++) {
             if (letter[i] === letter[y])
                return false;
        }
      }
      return true; 
    }
    

    通过不重复比较来提高效率

    【讨论】:

      【解决方案4】:

      这是一个使用@rafael 提出的方法的更有效的解决方案:按字母顺序重新排序单词并逐步将每个字母与下一个字母进行比较。如果有匹配,立即返回false。

      function isIsogram(word) {
          word = word.split('').sort().join('').toLowerCase();
        for (var i = 0; i < word.length; i++) {
          if (word[i] === word[i+1]) {
              return false;
          }
        }
        return true;
      }
      

      【讨论】:

      • 最有效的解决方案是使用Set 或对象来记住以前看到的字母(但实际上,对于如此小的数据,这不值得优化)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-03
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多