2014-07-17 82 views
1

所以我試圖在搜索中尋找這個,但最接近的我可以在幾種不同的語言中是類似的答案,我想用Javascript來做到這一點。返回字符串中的第一個非重複字符在javascript中

問題是我有一個任意字符串,我想返回第一個不重複的字符。 EX:'aba' - >會返回b 'aabcbd' - >會返回c。 這是我到目前爲止,只是一個簡單的循環開始。

var someString = 'aabcbd'; 



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

} 
}; 

http://jsfiddle.net/w7F87/ 不知道從這裏到

+0

非重複字符的索引性能測試將是奇數,這將是比字符不同在它之前。這應該足以讓你通過。 – tvanfosson

+0

我不明白,指數怎麼會很奇怪?在我的例子中,c在第三個索引中,但是如果它是aabbcd,那麼這意味着它將在第四個索引中。 – TaylorAllred

+0

他認爲它必須重複之前的角色 – dave

回答

8

可以使用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/

+0

你和戴夫都使用.charAt方法,我對此不熟悉。 – TaylorAllred

+1

@ user3806863:它獲取特定索引處的字符,'string.charAt(i)'與'string [i]'的作用相同,但它適用於所有瀏覽器。 – Guffa

+0

明白了,謝謝。 – TaylorAllred

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

+0

完美。謝謝。 – TaylorAllred

+1

僅供參考我認爲Guffa的答案更好 – dave

0

首先,在開始你的循環1,而不是0.檢查第一個字符看看它是否重複是沒有意義的,顯然它不可能。

現在,在你的循環中,你有someString [i]和someString [i - 1]。他們是當前和以前的角色。如果someString [i - 1] === someString [i - 1]那麼字符重複,如果someString [我]!== someString [我 - 1]然後他們不重複,所以你返回someString [我 - 1] ]

我不會寫了整個事情爲你,但希望這背後的思維過程將有助於

+0

這隻會檢查它是否重複之前的角色。他的例子表明它可以在任何地方重複 - 'abcdea'有一個重複的'a' – dave

+0

謝謝你理解我問Dave。謝謝你回答馬丁 – TaylorAllred

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

3

如果你要尋找的是隻發生一次的信中第一次出現,我會用另一種數據結構來跟蹤多少次中的每個字母已被看到。這可以讓你用O(n)而不是O來解決這個問題,只是在這種情況下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

+0

http://jsperf.com/24793051 – Xotic750

+0

@ Xotic750 - 這非常有趣。我想我假設對象索引是O(1)操作,但顯然不是。我想知道是否將其轉換爲整數可以改善這一點。 – tvanfosson

+0

使用'counts = {}'可能會有小的改進。值得注意的是,糟糕的Opera是如何,但是你的代碼通過瀏覽器獲得了巨大的提升。 – Xotic750

相關問題