【问题标题】:Check for repeated characters in a string Javascript检查字符串Javascript中的重复字符
【发布时间】:2016-02-12 21:46:59
【问题描述】:

我想知道是否有一种方法可以在不使用双循环的情况下检查字符串中的重复字符。这可以通过递归来完成吗?

使用双循环的代码示例(根据字符串中是否有重复字符返回真或假):

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

提前非常感谢!

【问题讨论】:

  • 你能添加一些将被检查的示例数据和预期的结果吗?
  • 在这种情况下什么算作字符串?例如一句话还是一个词?什么算作“重复”?多次出现?还是两个相邻的字母?
  • 需要递归吗?还是只有另一种选择?如果是这样,请检查我的更新答案。 :)
  • /(.).*\1/.test(str)

标签: javascript recursion repeat


【解决方案1】:

(可以在此答案的末尾找到递归解决方案。)

你可以使用javascript内置数组函数someMDN some reference

 var text = "test".split("");
 text.some(function(v,i,a){
   return a.lastIndexOf(v)!=i;
 });

回调参数:
v ...当前迭代值
i ...当前索引迭代
a ...当前数组

.split("") 从字符串创建一个数组
.some(function(v,i,a){ ... }) 去通过一个数组直到函数returns true,然后立即结束。 (不循环遍历整个数组,如果它更早找到匹配项)

some函数的详细信息可以在here

找到

测试,包含多个字符串:

var texts = ["test", "rest", "why", "puss"];

for(var idx in texts){
    var text = texts[idx].split("");
    document.write(text + " -> " + text.some(function(v,i,a){return a.lastIndexOf(v)!=i;}) +"<br/>");
    
  }
  //tested on win7 in chrome 46+

如果需要递归。

递归更新:

//recursive function
function checkString(text,index){
    if((text.length - index)==0 ){ //stop condition
        return false; 
    }else{
        return checkString(text,index + 1) 
        || text.substr(0, index).indexOf(text[index])!=-1;
    }
}

// example Data to test
var texts = ["test", "rest", "why", "puss"];

for(var idx in texts){
    var txt = texts[idx];
    document.write( txt +  " ->" + checkString(txt,0) + "<br/>");
}
//tested on win7 in chrome 46+

【讨论】:

    【解决方案2】:

    这样就可以了:

    function isIsogram (str) {
        return !/(.).*\1/.test(str);
    }
    

    【讨论】:

    • 这可能真的很有用。也很快,因为它使用正则表达式。我很惊讶这个答案没有更多的选票。
    • 太棒了!唯一的缺点可能是不太好理解,但是只要功能文档解释清楚就可以解决。
    【解决方案3】:

    您可以使用.indexOf().lastIndexOf() 来确定索引是否重复。意思是,如果字符的第一次出现也是最后一次出现,那么你知道它不会重复。如果不是真的,那么它会重复。

    var example = 'hello';
    
    var charRepeats = function(str) {
        for (var i=0; i<str.length; i++) {
          if ( str.indexOf(str[i]) !== str.lastIndexOf(str[i]) ) {
            return false; // repeats
          }
        }
      return true;
    }
    
    console.log( charRepeats(example) ); // 'false', because when it hits 'l', the indexOf and lastIndexOf are not the same.
    

    【讨论】:

    • 使用 toLowerCase() 将字符转换为相同大小写。
    【解决方案4】:
    function chkRepeat(word) {
        var wordLower = word.toLowerCase();
        var wordSet = new Set(wordLower);
        var lenWord = wordLower.length;
        var lenWordSet =wordSet.size;
    
        if (lenWord === lenWordSet) {
            return "false"
        } else {
            return'true'
        }
    }
    

    【讨论】:

    • 请提供一些细节或上下文,已经有一个接受的答案
    • 这是我最喜欢的查找单词中重复字符的方法,因为它利用了内置的 ES6 新的 Set 内置过滤数组中的重复项,但是它可以更简洁地写成这样:function chkRepeat (word) { return new Set(word.toUpperCase()).size == word.length }
    【解决方案5】:

    使用正则表达式解决=>

    function isIsogram(str){
      return !/(\w).*\1/i.test(str);
    }
    
    console.log(isIsogram("isogram"), true );
    console.log(isIsogram("aba"), false, "same chars may not be adjacent" );
    console.log(isIsogram("moOse"), false, "same chars may not be same case" );
    console.log(isIsogram("isIsogram"), false );
    console.log(isIsogram(""), true, "an empty string is a valid isogram" );

    【讨论】:

      【解决方案6】:

      所提出的算法的复杂度为(1 + n - (1)) + (1 + n - (2)) + (1 + n - (3)) + ... + (1 + n - (n-1)) = (n-1)*(1 + n) - (n)(n-1)/2 = (n^2 + n - 2)/2,即O(n2)。

      因此最好使用对象来映射并记住字符以检查唯一性或重复性。假设每个字符的最大数据大小,这个过程将是一个O(n) 算法。

      function charUnique(s) {
        var r = {}, i, x;
        for (i=0; i<s.length; i++) {
          x = s[i];
          if (r[x])
            return false;
          r[x] = true;
        }
        return true;
      }
      

      在一个很小的测试用例上,该函数的运行速度确实快了几倍。

      请注意,JavaScript 字符串被定义为 16 位无符号整数值序列。 http://bclary.com/2004/11/07/#a-4.3.16

      因此,我们仍然可以实现相同的基本算法,但使用更快的数组查找而不是对象查找。结果现在快了大约 100 倍。

      var charRepeats = function(str) {
        for (var i = 0; i <= str.length; i++) {
          for (var j = i + 1; j <= str.length; j++) {
            if (str[j] == str[i]) {
              return false;
            }
          }
        }
        return true;
      }
      
      function charUnique(s) {
        var r = {},
          i, x;
        for (i = 0; i < s.length; i++) {
          x = s[i];
          if (r[x])
            return false;
          r[x] = true;
        }
        return true;
      }
      
      function charUnique2(s) {
        var r = {},
          i, x;
        for (i = s.length - 1; i > -1; i--) {
          x = s[i];
          if (r[x])
            return false;
          r[x] = true;
        }
        return true;
      }
      
      function charCodeUnique(s) {
        var r = [],
          i, x;
        for (i = s.length - 1; i > -1; i--) {
          x = s.charCodeAt(i);
          if (r[x])
            return false;
          r[x] = true;
        }
        return true;
      }
      
      function regExpWay(s) {
        return /(.).*\1/.test(s);
      }
      
      
      function timer(f) {
        var i;
        var t0;
      
        var string = [];
        for (i = 32; i < 127; i++)
          string[string.length] = String.fromCharCode(i);
        string = string.join('');
        t0 = new Date();
        for (i = 0; i < 10000; i++)
          f(string);
        return (new Date()) - t0;
      }
      
      document.write('O(n^2) = ',
        timer(charRepeats), ';<br>O(n) = ',
        timer(charUnique), ';<br>optimized O(n) = ',
        timer(charUnique2), ';<br>more optimized O(n) = ',
        timer(charCodeUnique), ';<br>regular expression way = ',
        timer(regExpWay));

      【讨论】:

        【解决方案7】:

        使用 lodash 的另一种方法

        var _ = require("lodash");
        var inputString = "HelLoo world!"
        var checkRepeatition = function(inputString) {
          let unique = _.uniq(inputString).join('');
          if(inputString.length !== unique.length) {
            return true; //duplicate characters present!
          }
          return false;
        };
        console.log(checkRepeatition(inputString.toLowerCase()));
        

        【讨论】:

          【解决方案8】:

          您可以使用“设置对象”!

          Set 对象允许您存储任何类型的唯一值,无论是 原始值或对象引用。它有一些方法可以添加或检查对象中是否存在属性。

          Read more about Sets at MDN

          我是如何使用它的:

           function isIsogram(str){
            let obj = new Set();
          
            for(let i = 0; i < str.length; i++){
              if(obj.has(str[i])){
                return false
              }else{
                obj.add(str[i])
              }
            }
            return true
          }
          
          isIsogram("Dermatoglyphics") // true
          isIsogram("aba")// false
          

          【讨论】:

            【解决方案9】:
             const str = "afewreociwddwjej";
              const repeatedChar=(str)=>{
              const result = [];
              const strArr = str.toLowerCase().split("").sort().join("").match(/(.)\1+/g);
              
              if (strArr != null) {
                strArr.forEach((elem) => {
                  result.push(elem[0]);
                });
              }
              return result;
            }
            console.log(...repeatedChar(str));
            

            你也可以使用下面的代码来查找字符串中的重复字符

            【讨论】:

              【解决方案10】:

              //Finds character which are repeating in a string
              var sample = "success";
              function repeatFinder(str) {
                  let repeat="";
                  for (let i = 0; i < str.length; i++) {
                      for (let j = i + 1; j < str.length; j++) {
                          if (str.charAt(i) == str.charAt(j) && repeat.indexOf(str.charAt(j)) == -1) {
                              repeat += str.charAt(i);
                          }
                      }
                  }
                  return repeat;
              }
              console.log(repeatFinder(sample)); //output: sc

              【讨论】:

                【解决方案11】:
                let myString = "Haammmzzzaaa";
                
                myString = myString
                   .split("")
                   .filter((item, index, array) => array.indexOf(item) === index)
                   .join("");
                   
                console.log(myString); // "Hamza"
                

                【讨论】:

                • 虽然此代码可以回答问题,但提供有关 如何 和/或 为什么 解决问题的附加上下文将改善答案的长期价值。
                猜你喜欢
                • 2018-11-28
                • 2015-01-22
                • 2018-08-19
                • 2021-03-27
                • 2015-10-20
                • 1970-01-01
                • 2014-10-19
                • 2023-03-31
                • 2011-12-17
                相关资源
                最近更新 更多