Michael Dobbertin
Michael Dobbertin

Reputation: 77

What's the most efficient way to evaluate if a string is a palindrome using Javascript?

I'm new to Javascript and wrote the code below to determine if a string is a palindrome. I'm curious as to what is the most efficient way to accomplish the same task.

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

Upvotes: 2

Views: 2295

Answers (6)

King Friday
King Friday

Reputation: 26086

unreadable + unmaintainable + terse + efficient + recursive + non-branching

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

Fiddle: http://jsfiddle.net/namcx0yf/

Upvotes: 0

Trenin
Trenin

Reputation: 2063

To be efficient, you should avoid unnecessary computations. Ask yourself:

  • do you need to remove spaces?
  • do you need to convert to an array?
  • do you need to allocate new objects for the left and right strings?
  • do you need to reverse the string?

The checking can be done in a very simple loop:

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

To ignore spaces and non-alpha numeric characters, it can be re-written as follows:

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

Upvotes: 0

JLRishe
JLRishe

Reputation: 101738

It's not clear if you're talking about efficiency in terms of code length, or amount of computation, but this should be fairly good in both regards. And it takes into account non-alpha characters beside spaces as well as capitalization:

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

A much shorter approach (though perhaps more computation intensive):

function isPalindrome(str) {
   str = str.toLowerCase().replace(/[^a-z]/g, '');

   return str == str.split("").reverse().join("");
}

And if you really want that alert stuff, I'd suggest putting it in a separate function:

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

Upvotes: 3

emcas88
emcas88

Reputation: 901

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

You made a few unnecesary operations.

Upvotes: 1

aksu
aksu

Reputation: 5235

I think this one is lot simpler:

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

See more: Palindrome check in Javascript

Upvotes: 1

Matt
Matt

Reputation: 20796

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

Upvotes: 3

Related Questions