简体   繁体   English

检查字符串 Javascript 中的重复字符

[英]Check for repeated characters in a string Javascript

I was wondering if there is a way to check for repeated characters in a string without using double loop.我想知道是否有一种方法可以在不使用双循环的情况下检查字符串中的重复字符。 Can this be done with recursion?这可以用递归来完成吗?

An example of the code using double loop (return true or false based on if there are repeated characters in a string):使用双循环的代码示例(根据字符串中是否存在重复字符返回 true 或 false):

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;
}

Many thanks in advance!提前谢谢了!

This will do:这将做:

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

(A recursive solution can be found at the end, of this answer.) (可以在此答案的末尾找到递归解决方案。)

You could just use the builtin javascript Array functions some MDN some reference你可以只使用内置的 javascript 数组函数some MDN 一些参考

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

callback parameters:回调参数:
v ... current value of the iteration v ... 迭代的当前值
i ... current index of the iteration i ... 迭代的当前索引
a ... array being iterated一个...数组被迭代

.split("") create an array from a string .split("")从字符串创建数组
.some(function(v,i,a){ ... }) goes through an array until the function returns true , and ends than right away. .some(function(v,i,a){ ... })遍历一个数组,直到函数returns true ,然后立即结束。 (it doesn't loop through the whole array, which is good for performance) (它不会遍历整个数组,这对性能有好处)

Details to the some function here in the documentation 文档某些功能的详细信息

Tests, with several different strings:测试,有几个不同的字符串:

 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+

If recursion is really needed.如果确实需要递归。

Update for recursion:递归更新:

 //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+

you can use .indexOf() and .lastIndexOf() to determine if an index is repeated.您可以使用.indexOf().lastIndexOf()来确定索引是否重复。 Meaning, if the first occurrence of the character is also the last occurrence, then you know it doesn't repeat.意思是,如果字符的第一次出现也是最后一次出现,那么你知道它不会重复。 If not true, then it does repeat.如果不是真的,那么它会重复。

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.
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'
    }
}

Using regex to solve=>使用正则表达式解决=>

 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" );

The algorithm presented has a complexity of (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 which is O(n 2 ).所提出的算法的复杂度为(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(n 2 )。

So it would be better to use an object to map and remember the characters to check for uniqueness or duplicates.所以最好使用对象来映射并记住字符以检查唯一性或重复性。 Assuming a maximum data size for each character, this process will be an O(n) algorithm.假设每个字符的最大数据大小,这个过程将是一个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;
}

On a tiny test case, the function indeed runs a few times faster.在一个很小的测试用例中,该函数的运行速度确实快了几倍。

Note that JavaScript strings are defined as sequences of 16-bit unsigned integer values.请注意,JavaScript 字符串被定义为 16 位无符号整数值的序列。 http://bclary.com/2004/11/07/#a-4.3.16 http://bclary.com/2004/11/07/#a-4.3.16

Hence, we can still implement the same basic algorithm but using a much quicker array lookup rather than an object lookup.因此,我们仍然可以实现相同的基本算法,但使用更快的数组查找而不是对象查找。 The result is approximately 100 times faster now.结果现在快了大约 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));

Another way of doing it using lodash使用 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()));

You can use "Set object"!您可以使用“设置对象”!

The Set object lets you store unique values of any type, whether primitive values or object references. Set 对象允许您存储任何类型的唯一值,无论是原始值还是对象引用。 It has some methods to add or to check if a property exist in the object.它有一些方法可以添加或检查对象中是否存在属性。

Read more about Sets at MDN 在 MDN 上阅读有关 Set 的更多信息

Here how i use it:这里我如何使用它:

 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
 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));

You can also use the following code to find the repeated character in a string您还可以使用以下代码查找字符串中的重复字符

 //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

let myString = "Haammmzzzaaa";

myString = myString
   .split("")
   .filter((item, index, array) => array.indexOf(item) === index)
   .join("");
   
console.log(myString); // "Hamza"
   const checkRepeats = (str: string) => {
   const arr = str.split('')
   const obj: any = {}
   for (let i = 0; i < arr.length; i++) {
    if (obj[arr[i]]) {
        return true
    }
    obj[arr[i]] = true
  }
     return false
 }

 console.log(checkRepeats('abcdea'))
function repeat(str){
let h =new Set()
for(let i=0;i<str.length-1;i++){
    let a=str[i]
    if(h.has(a)){
        console.log(a)
    }else{
        h.add(a)
    }
}
return 0

} let str = ' } 让 str = '

 function repeat(str){ let h =new Set() for(let i=0;i<str.length-1;i++){ let a=str[i] if(h.has(a)){ console.log(a) }else{ h.add(a) } } return 0 } let str = 'haiiiiiiiiii' console.log(repeat(str))

' console.log(repeat(str)) ' console.log(重复(str))

Cleanest way for me:对我来说最干净的方式:

  • Convert the string to an array将字符串转换为数组
  • Make a set from the array从数组中创建一个集合
  • Compare the length of the set and the array比较集合和数组的长度

Example function:示例函数:

function checkDuplicates(str) {
  const strArray = str.split('');
  if (strArray.length !== new Set(strArray).size) {
    return true;
  }
  return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM