【问题标题】:What's the most efficient way to evaluate if a string is a palindrome using Javascript?使用Javascript评估字符串是否为回文的最有效方法是什么?
【发布时间】:2014-02-03 19:58:11
【问题描述】:

我是 Javascript 新手,并编写了以下代码来确定字符串是否为回文。我很好奇完成相同任务的最有效方法是什么。

var isPalindrome = function (string) {
    var leftString = [];
    var rightString = [];

    // Remove spaces in the string and convert to an array
    var strArray = string.split(" ").join("").split("");    
    var strLength = strArray.length;

    // Determine if the string is even or odd in length, then assign left and right strings accordingly
    if (strLength % 2 !== 0) {
        leftString = strArray.slice(0, (Math.round(strLength / 2) - 1));
        rightString = strArray.slice(Math.round(strLength / 2), strLength);
    } else {
        leftString = strArray.slice(0, (strLength / 2));
        rightString = strArray.slice((strLength / 2, strLength))
    }

    if (leftString.join("") === rightString.reverse().join("")) {
        alert(string + " is a palindrome.");
    } else {
        alert(string + " is not a palindrome.")
    }

}


isPalindrome("nurses run");

【问题讨论】:

  • Firebug 有 javascript 分析工具。尝试几种不同的方法,看看你能获得什么性能。
  • 如果您关心性能,请搜索“jsperf palindrome”,您会看到类似this
  • 这听起来像是家庭作业。 :)

标签: javascript


【解决方案1】:
function isPalindrome( s )
{
   var i = 0, j = s.length-1;
   while( i < j )
       if( s[i++].toLowerCase() != s[j--].toLowerCase() ) return false;
   return true;
}

【讨论】:

    【解决方案2】:

    不清楚您是在谈论代码长度还是计算量方面的效率,但这在这两方面都应该相当不错。它还考虑了空格旁边的非字母字符以及大写:

    function isPalindrome(str) {
       var i, len;
    
       str = str.toLowerCase().replace(/[^a-z]/g, '');
       len = str.length;
    
       for(i = 0; i < len / 2; i += 1) {
          if(str.charCodeAt(i) != str.charCodeAt(len - i - 1)) {
             return false;
          }
       }
    
       return true;
    }
    

    一种更短的方法(尽管可能需要更多的计算):

    function isPalindrome(str) {
       str = str.toLowerCase().replace(/[^a-z]/g, '');
    
       return str == str.split("").reverse().join("");
    }
    

    如果你真的想要那种提醒的东西,我建议把它放在一个单独的函数中:

    function isPalindromeAlert(str) {
      alert(str + "is " + (isPalindrome(str) ? "" : "not ") + "a palindrome.");
    }
    

    【讨论】:

      【解决方案3】:

      我认为这个要简单得多:

      var isPalindrome = function (string) {
          if (string == string.split('').reverse().join('')) {
              alert(string + ' is palindrome.');
          }
          else {
              alert(string + ' is not palindrome.');
          }
      }
      

      查看更多:Palindrome check in Javascript

      【讨论】:

      • 我认为拆分、反转和加入效率不高。
      • 这是如何工作的?我不明白拆分、反转和加入是如何在这里工作的。除非您对不明显的输入做出假设......
      • 这也将始终返回 true,if 语句从不将字符串与任何内容进行比较,它只是检查您是否能够反转字符串
      • 不应该是string === string.split('').reverse().join('')吗?
      • @asku 拆分和加入的意义何在?你不能把它倒过来比较一下吗?
      【解决方案4】:
      var str = "abcba";
      var len = str.Lenght;
      var index = 0;
      
      while(index <= len/2 && str[index] == str[len - index - 1]) index++;
      
      if(index == len/2) {
          alert(string + " is a palindrome.");
      }
      else {
         alert(string + " is not a palindrome.");
      }
      

      你做了一些不必要的操作。

      【讨论】:

        【解决方案5】:

        为了提高效率,您应该避免不必要的计算。问问自己:

        • 是否需要删除空格?
        • 需要转换成数组吗?
        • 是否需要为左右字符串分配新对象?
        • 需要反转字符串吗?

        检查可以在一个非常简单的循环中完成:

        var len=string.length;
        for (int i=0; i<(len/2); i++) {
          if (string[i] != string[len-i-1]) {
            alert(string + " is not a palindrome.");
            return;
          }
        }
        alert(string + " is a palindrome.");
        

        要忽略空格和非字母数字字符,可以改写如下:

        function isAlphaNumeric( chr ) {
          return ( ((c >= 'a') && (c <= 'z')) ||
                   ((c >= 'A') && (c <= 'Z')) ||
                   ((c >= '0') && (c <= '9')) );
        }
        
        // Note - template taken from @Matt's answer!
        function isPalindrome( string ) {
          var i = 0, j = s.length-1;
          while( i < j ) {
            if (isAlphaNumeric(string[i])) {
              if (isAlphaNumeric(string[j])) {
                if ( string[i++].toLowerCase() != string[j--].toLowerCase() ) 
                  return false;
              } else {
                j--;
              }
            } else {
              i++;
              if (!isAlphaNumeric(string[j])) j--;
            }
          }
          return true;
        }
        

        【讨论】:

        • 通常,回文检查应该忽略空格和其他非字母字符。
        • @JLRishe 也许跳过循环内的那些字符而不是创建整个中间对象更有效...例如,如果字符串是a--------b,那么一个新字符串ab在处理原始字符串中的所有10 字符后创建。只有这样才能检查回文(这是一个词吗?)。这个和其他一些答案会在第一次检查时看到'a'!='b',所以会立即返回。
        • 好的,但我希望你喜欢编码(并确保它没有任何错误)。通常,可读代码优于带有微优化的过度代码。
        • @JLRishe OP 要求最有效的方式,而不是最易读的方式。而且我确实喜欢编写代码!
        【解决方案6】:

        不可读 + 不可维护 + 简洁 + 高效 + 递归 + 非分支

        function isPalindrome(s,i) {
         return (i=i||0)<0|| i>=s.length/2|| s[i]==s[s.length-1-i]&& isPalindrome(s,++i);
        }
        

        小提琴:http://jsfiddle.net/namcx0yf/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-28
          • 2013-05-17
          • 1970-01-01
          • 2020-10-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多