在javascript中返回字符串中的第一个非重复字符

时间:2014-07-17 00:29:52

标签: javascript

所以我试着在搜索中寻找这个,但我能来的最接近的是几种不同语言的类似答案,我想用Javascript来做。

问题是我有一个任意字符串,我想返回第一个非重复字符。 EX:'aba' - >将返回b 'aabcbd' - >将返回c。 这是我到目前为止,只是一个简单的for循环开始。

var someString = 'aabcbd';



var firstNonRepeatedCharacter = function(string) {
for(var i = 0; i < someString.length; i++){

}
};

http://jsfiddle.net/w7F87/ 不知道从哪里开始

28 个答案:

答案 0 :(得分:16)

您可以使用indexOf方法查找非重复字符。如果您在字符串中查找字符,它将是第一个找到的字符,并且您不会在其后找到另一个字符:

function firstNonRepeatedCharacter(string) {
  for (var i = 0; i < string.length; i++) {
    var c = string.charAt(i);
    if (string.indexOf(c) == i && string.indexOf(c, i + 1) == -1) {
      return c;
    }
  }
  return null;
}

演示:http://jsfiddle.net/Guffa/Se4dD/

答案 1 :(得分:3)

如果您正在寻找仅出现一次的字母的第一次出现,我会使用另一种数据结构来跟踪每个字母被看到的次数。这可以让你使用O(n)而不是O(n 2 )解决方案,除了在这种情况下n是最小和最大字符代码之间的差异或者字符串的长度因此无法直接比较。

注意:使用for-in的早期版本 - 实际上变得非常慢。我已经更新它以使用字符代码作为索引来尽可能快地保持查找。我们真正需要的是哈希表,但是考虑到N的小值和相对较小的相对加速,对于这个问题,它可能不值得。事实上,你应该更喜欢@ Guffa的解决方案。我之所以包括我只是因为我最终从中学到了很多东西。

function firstNonRepeatedCharacter(string) {
   var counts = {};
   var i, minCode = 999999, maxCode = -1;
   for (i = 0; i < string.length; ++i) {
        var letter = string.charAt(i);
        var letterCode = string.charCodeAt(i);
       if (letterCode < minCode) {
           minCode = letterCode;
       }
       if (letterCode > maxCode) {
           maxCode = letterCode;
       }
        var count = counts[letterCode];
        if (count) {
           count.count = count.count + 1;
        }
        else {
            counts[letterCode] = { letter: letter, count: 1, index: i };
        }
   }

    var smallestIndex = string.length;
    for (i = minCode; i <= maxCode; ++i) {
       var count = counts[i];
       if (count && count.count === 1 && count.index < smallestIndex) {
          smallestIndex = count.index;
       }
   }

    return smallestIndex < string.length ? string.charAt(smallestIndex) : '';
}

请参阅http://jsfiddle.net/b2dE4/

小提琴

http://jsperf.com/24793051/2

的性能测试(与评论略有不同)

答案 2 :(得分:2)

var firstNonRepeatedCharacter = function(string) {
  var chars = string.split('');
  for (var i = 0; i < string.length; i++) {
    if (chars.filter(function(j) { 
                        return j == string.charAt(i); 
               }).length == 1) return string.charAt(i);
  }
};

所以我们通过拆分任何东西来创建一个包含所有字符的数组。

然后,我们循环遍历每个字符,并且我们过滤我们创建的数组,因此我们将获得仅包含这些字符的数组。如果长度为1,我们知道我们有一个不重复的字符。

小提琴:http://jsfiddle.net/2FpZF/

答案 3 :(得分:2)

此解决方案应适用于带有整数和字符串的数组。

function firstNoneRepeating(list, map = new Map()) {
  for (let item of list) {
    if (map.has(item)) {
      map.set(item, map.get(item) + 1);
    } else {
      map.set(item, 1);
    }
  }
  for (let [key, value] of map.entries()) {
    if (value === 1) {
      return key;
    }
  }
}
console.log(firstNoneRepeating("aabcbd"));
console.log(firstNoneRepeating([5, 2, 3, 4, 2, 6, 7, 1, 2, 3]));

答案 4 :(得分:1)

首先,开始你的循环为1,而不是0.检查第一个字符是否有重复,显然它不能重复。

现在,在你的循环中,你有someString [i]和someString [i - 1]。它们是当前和以前的角色。

如果someString [i] === someString [i - 1]则字符重复,如果someString [i]!== someString [i - 1]那么它们不重复,所以你返回someString [i]

我不会为你写出整件事,但希望这背后的思考过程能有所帮助

答案 5 :(得分:1)

 function FirstNotRepeatedChar(str) {
 var arr = str.split('');
 var result = '';
 var ctr = 0; 
  for (var x = 0; x < arr.length; x++) {
   ctr = 0;
  for (var y = 0; y < arr.length; y++) {
  if (arr[x] === arr[y]) {
    ctr+= 1;
    }
   }

if (ctr < 2) {
  result = arr[x];
  break;
  }
}
return result;
}
console.log(FirstNotRepeatedChar('asif shaik'));

答案 6 :(得分:1)

let str='aabcbd'
let ans=''
for (let i=0;i<str.length;i++){
    if(str.indexOf(str.charAt(i))===str.lastIndexOf(str.charAt(i))){
    ans+=str.charAt(i)
    break
    }
}
console.log(ans)

答案 7 :(得分:1)

这是使用Regex替换所有重复字符然后返回第一个字符的解决方案。

function firstNonRepeat(str) {

   // Sorting str so that all repeating characters will come together & replacing it with empty string and taking first character using substr.

   var rsl = str.split('').sort().join('').replace(/(\w)\1+/g,'').substr(0,1);

   if(rsl) return rsl;

   else return 'All characters are repeated in ' + str;

}

console.log(firstNonRepeat('aaabcccdeeef'));
console.log(firstNonRepeat('aaacbdcee'));
console.log(firstNonRepeat('aabcbd'));

答案 8 :(得分:0)

下面的解决方案是一种频率计数器模式,它只会运行一个循环,因此时间复杂度为 O(n)。

function firstNotRepeatingCharacter(str) {
  const obj = {};
  for (let i = 0, L = str.length; i < L; i++) {
    const char = str[i];
    obj[char] = obj[char] ? obj[char] + 1 : 1;
  }

  for (let key of Object.keys(obj)) {
    if (obj[key] == 1) {
      return key;
    }
  }
  return -1;
}

答案 9 :(得分:0)

下面的实现具有很好的时间复杂度,它考虑了不同大小写的字母:

步骤 必须触摸字符串中的每个字符才能知道它是否重复

function firstNonRepeatingLetter(wordd) {

    const chars = {}

    let word = wordd.toLowerCase()

    // go through chars
    // store chars in hash with values of array storing index of char and true if only 1 encountered so far
    for (let i = 0; i < word.length; i += 1) {
        let char = word[i]
        if (chars[char]) {
            chars[char][0] = false
        } else {
            chars[char] = [true, i]
        }
    }
    let output = ''
    let index;
    for (let key in chars) {
    // return char with true and lowest index
        if (chars[key][0]) {
            index = index === undefined ? chars[key][1] : index
            if (index >= chars[key][1]) {
                output = key
            }
        }
    }
    return index === undefined ? '' : wordd[index]
}
console.log(firstNonRepeatingLetter('sTreSS')) //T```

答案 10 :(得分:0)

最令人满意且易于理解的答案如下。

function firstNotRepeatingCharacter(s) {
        
    const arr = s.split("");

    for(let i = 0; i < arr.length; i++){
        let chr = arr[i];
        if( arr.indexOf(arr[i]) == arr.lastIndexOf(arr[i])){
            return arr[i]
        }            
    }
    
    return "_"
}

说明:它从正向和反向循环遍历字符串的所有字符,然后比较值。如果向前和向后搜索的索引均为true,则它将返回该字符。

答案 11 :(得分:0)

我使用object跟踪字符串中的字符数,然后返回fa值为1的char。这是一个演示:

function firstNotRepeatingCharacter(s) {

// initialize an empty object to store chars

    let seen = {};
    let letter = '';

  // iterate over each char in a string
  // if it is already there increase value by one
  // else set the value to 1

    for(let char of s){
            if (seen[char]){
                    seen[char] +=1;
            } else {
                    seen[char] = 1;
            }
    }

  // iterate over the new constructed object
  // if the value is 1 and the output variable is empty
  // return the associated key to the value 1
  // else return '_'

    for(let v in seen){
        while(seen[v] == 1 && letter === ''){
            letter += v;
            return letter;
        } 
    }
return('_');
}

console.log(firstNotRepeatingCharacter("abacabad"));
console.log(firstNotRepeatingCharacter("cbc"));
console.log(firstNotRepeatingCharacter("bcccccccccccccyb"));
console.log(firstNotRepeatingCharacter("aaa"));

答案 12 :(得分:0)

    //To find first non repeating letter 
    //It will check for both upper and lower case
    //only use one String.indexOf()

    var mystr="ohvhvtccggt";
    var checkFirstNonRepeating=function(){
    var ele=[];
      for(var i=0;i<mystr.length;i++) {
      var key=mystr.charAt(i);
      if(!ele[key])
          ele[key]=0;
      ele[key]++;

   //Just check for second occurance of character 
   //no need to use indexOf twice

       if(mystr.indexOf(key,i+1)==-1 && ele[key]<2)  
         return mystr[i];
       }
     return "All repeating letters";
    }
    console.log(checkFirstNonRepeating());
              
        /*
        Input  : "ohvhvtoccggt"
        Output : All repeating letters
        Input  :"oohjtht"
        Output :j 
        */

答案 13 :(得分:0)

我们可以跟踪对象中字符串每个字符的频率。 例如:对于“ aabcbd”,我们可以将频率存储为

{“ a”:2,“ b”:2,“ c”:1,“ d”:1}

这将花费O(n)时间。 然后,我们可以遍历此对象并找到频率为1的第一个字符,这也将花费O(n)时间。因此,这种方法的时间复杂度将为O(n)。

const firstNonRepeating=(str)=>{
const obj={};
str.split("").forEach(item=>{
  obj[item] 
  ? obj[item]++ 
  : obj[item]=1;
});
const item = Object.keys(obj).find(key=> obj[key] === 1);
return item;
}

注意:我使用的ES6 Object.keys方法可能在较旧的版本中不起作用 浏览器。

答案 14 :(得分:0)

这是另一个使用数组的解决方案,使用26个唯一字符作为数组的长度:

var firstUniqChar = (function(s) {
    var arr = [];
    var str = s.toLowerCase();
    for(let c of str){
      let index = c.charCodeAt(0) - "a".charCodeAt(0);
      arr[index]? ++arr[index]: arr[index]=1;
    }
    
    for(let c of str){
      let index = c.charCodeAt(0) - 97;
      if(arr[index] == 1){
        return c;
      };
    }

    return -1;
}("aabcbd"));

console.log(firstUniqChar);

答案 15 :(得分:0)

解决此算法的简便方法,非常简单

function firstNonRepeatChar(str){
    let map = {};
    for(let i=0; i<str.length; i++){
        if(Object.keys(map).includes(str[i])){
            map[str[i]]++
        }
        else{
            map[str[i]] = 1;
        }
    }

    for(let j=0; j< Object.values(map).length; j++){
        if(Object.values(map)[j] == 1){
            console.log(Object.keys(map)[j]);
            return
        }
        if (j == Object.values(map).length-1 && Object.values(map)[j] != 1){
            console.log('_');
            return;
        }
        else{
            continue;
        }
    }
}

nonRepeat("aaabbcccdeeef");

答案 16 :(得分:0)

function firstUniqChar(str) {
    let myMap = new Map();
    for(let i = 0; i < str.length; i++) {
        let char = str.charAt(i);
        if(!myMap.has(char)) {
            myMap.set(char, 0);
        }
        myMap.set(char, myMap.get(char) + 1 );
    }
    for(let [key, value] of myMap) {
       if(value === 1) {
           return key;
       }
    }
    return null;
}

let result = firstUniqChar("caabbdccee");
console.log(result);

您可以使用Map Object并设置键和值,在该值中存储该特定字符的计数,然后您可以遍历map并检查值1在哪里并返回该键。

地图对象会记住键的原始插入顺序。

答案 17 :(得分:0)

> var firstNonRepeatedCharacter = function (str){   
> for(i=0;i<str.length;i++){
>     if(str.indexOf(str.charAt(i)) === str.lastIndexOf(str.charAt(i))){
>       console.log(str.charAt(i));
>       break;
>     }   } }
> 
> firstNonRepeatedCharacter ("areerak");

您可以在下面的链接中查看

https://codepen.io/t3veni/pen/wvvxJzm

答案 18 :(得分:0)

这是另一种方法:

每次您发现相等的字符将其存储在数组中并退出循环。如果在数组中未找到字符,则您将拥有第一个非重复字符

function nonRepeatingChars(value) {
  const memory = []
  for (let i = 0; i < value.length; i++) {
    for (let j = i + 1; j < value.length; j++) {
      if (value[i] === value[j]) {
        memory.push(value[j])
        break;
      }
    }
    if (!memory.some(x => x === value[i])) {
      return value[i];
    }
  }
  return "all chars have duplicates";
}

console.log('First non repeating char is:',nonRepeatingChars("esen"))
console.log('First non repeating char is:',nonRepeatingChars("esesn"))
console.log('First non repeating char is:',nonRepeatingChars("eseulsn"))
console.log('First non repeating char is:',nonRepeatingChars("esesnn"))

答案 19 :(得分:0)

这是我使用forEach并将字符串转换为数组的解决方案
function firstNotRepeatingCharacter(s) {
    var strArr = s.split("");
    var found = "_";
    strArr.forEach(function(item, index) {
        if (strArr.indexOf(item) == index && strArr.indexOf(item, index + 1) == -1) {
            if (found === "_") {
                found = item;
            }
        }
    })

    return found;
}

firstNotRepeatingCharacter("abacabad")

答案 20 :(得分:0)

这是我的解决方案,其时间复杂度为o(n)

function getfirstNonRepeatingCharacterInAString(params) {
    let count = {};
    for (let i = 0; i < params.length; i++) {
        let count1 = 0;
        if (!count[params.charAt(i)]) {
            count[params.charAt(i)] = count1 + 1;
        }
        else {
            count[params.charAt(i)] = count[params.charAt(i)] + 1;
        }
    }
    for (let key in count) {
        if (count[key] === 1) {
            return key;
        }
    }
    return null;
}
console.log(getfirstNonRepeatingCharacterInAString("GeeksfoGeeks"));

答案 21 :(得分:0)

解决方案:将字符映射到对象中

首先,将一个空对象初始化为countchar中的每个count被分配为输入字符串中的每个字母。

如果{{1}中尚不存在letter,则为count分配一个值letter。否则,如果1已经存在,则将其出现的次数增加letter

循环遍历输入字符串中的每个字母并将每个字母分配给1中的键值对之后,下一步是循环遍历{{1 }}。

遍历count中的属性时,等于count的第一个属性是输入字符串中的第一个非重复字符。

调用count的预期实际输出为1

firstNonRepeatedCharacter(someString)

答案 22 :(得分:0)

let arr = [10, 5, 3, 4, 3, 5, 6];
outer:for(let i=0;i<arr.length;i++){
    for(let j=0;j<arr.length;j++){
        if(arr[i]===arr[j+1]){
            console.log(arr[i]);
            break outer;
        }
    }
}


//or else you may try this way...
function firstDuplicate(arr) {
    let findFirst = new Set()
    for (element of arr)
        if (findFirst.has(element ))
            return element 
        else
            findFirst.add(element )
}

答案 23 :(得分:0)

您可以遍历每个字符到find()返回第一个match()的第一个字母。这将导致给定字符串中的第一个非重复字符:

const first_nonrepeated_character = string => [...string].find(e => string.match(new RegExp(e, 'g')).length === 1);
const string = 'aabcbd';

console.log(first_nonrepeated_character(string)); // c

答案 24 :(得分:0)

我遇到类似问题时遇到了这个问题。让我添加我的2行。 我所做的与Guffa的答案类似。但是同时使用indexOf方法和lastIndexOf

我的方法:

function nonRepeated(str) {
   for(let i = 0; i < str.length; i++) {
      let j = str.charAt(i)
      if (str.indexOf(j) == str.lastIndexOf(j)) {
        return j;
      }
   }
   return null;
}

nonRepeated("aabcbd"); //c

简单地,indexOf()首次出现字符,而lastIndexOf()最终出现字符。因此,当第一个出现也是==最后一个出现时,表示只有一个字符。

答案 25 :(得分:0)

这是一个O(n)解决方案,具有2个ES6集,一个跟踪所有出现的字符,而一个跟踪仅出现一次的字符。此解决方案利用了Set保留的插入顺序。

const firstNonRepeating = str => {
  const set = new Set();
  const finalSet = new Set();
  str.split('').forEach(char => {
    if (set.has(char)) finalSet.delete(char);
    else {
      set.add(char);
      finalSet.add(char);
    }
  })
  const iter = finalSet.values();
  return iter.next().value;
}

答案 26 :(得分:0)

用零填充一个空数组,其长度与字符串数组相同,并计算它们在循环中出现的次数。抓取计算数组中的第一个值为1。

function firstNotRepeatingCharacter(s) {
    const array = s.split("");
    let scores = new Array(array.length).fill(0);

    for (let char of array) {
        scores[array.indexOf(char)]++;
    }

    const singleChar = array[scores.indexOf(1)];
    return singleChar ? singleChar : "_"
}

答案 27 :(得分:0)

使用ECMA5阵列方法的另外两种可能性。如果不存在,将返回undefined

的Javascript

function firstNonRepeatedCharacter(string) {
    return string.split('').filter(function (character, index, obj) {
        return obj.indexOf(character) === obj.lastIndexOf(character);
    }).shift();
}

console.log(firstNonRepeatedCharacter('aabcbd'));

jsFiddle

或者如果你想要更好的性能,特别是在较长的字符串上。

的Javascript

function firstNonRepeatedCharacter(string) {
    var first;

    string.split('').some(function (character, index, obj) {
        if(obj.indexOf(character) === obj.lastIndexOf(character)) {
            first = character;
            return true;
        }

        return false;
    });

    return first;
}

console.log(firstNonRepeatedCharacter('aabcbd'));

jsFiddle