Js判斷一個單詞是否有重復字母


今天上午刷到一道題,大體是寫一個方法判斷一個單詞中是否有重復的字母(或者說一個字符串中是否有重復的字符)。我的思路是一個字符一個字符地遍歷,如果發現有重復的停止:

 1 function isIsogram(str) {
 2   str = str.toLowerCase();
 3   
 4   for (var i = 0; i < str.length; i++) {
 5     if (str.indexOf(str.charAt(i), i + 1) >= 0) {
 6       return false;
 7     }
 8   }
 9   
10   return true;
11 }

這種簡單的場景下談性能沒什么意義,兩次循環速度並不慢( str.indexOf() 也認為是一次循環,但由於是native的行為,速度很快)。 后來我看到了別的用正則的實現,雖然很簡單,但一開始我確實沒住這方面想:

1 function isIsogram2(str) {
2   return !/(.).*\1/i.test(str);
3 }

或者:

function isIsogram2(str) {
  return !/^.*(.).*\1/i.test(str);
}

這兩個其實沒什么區別,前者優先查找字符串尾端,后者優先查找字符串前端。這個正則比較好理解,不多解釋,比較讓我驚訝的這個匹配的性能。因為判斷一個字符串是否有重復字符這樣的任務太簡單,正因為太簡單,所以代表目標字符串的規律性太小。如果用正則必然帶來大量嘗試和回溯,其實主觀上會讓人覺得性能很不好。不過好不好不是隨便想一想就行的,還是要驗證一下。決定性能到底是好是壞,當然看最壞情況下,兩個算法的執行時間。構造這樣一個單詞: qwertyuiopas,沒有字母重復,意味着兩種算法都要跑完整的循環。

 1 console.time("loop");
 2 for(var i=0; i<400000; i++){
 3     isIsogram("qwertyuiopas");
 4 }
 5 console.timeEnd("loop");
 6  
 7 console.time("regexp");
 8 for(var i=0; i<400000; i++){
 9     isIsogram2("qwertyuiopas");
10 }
11 console.timeEnd("regexp");

 看看運行結果: amazing! 這個實驗證實了一個問題:javascript對正則確實有優化,使用正則的效率非常高。當然這句話也可以反過來理解,javascript中的字符串操作、循環太慢了。那么,對於正則還等什么呢,趕快用起來吧 轉載  周驊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM