简体   繁体   中英

I am having trouble with a palindrome function in javascript

This is my code: The function works well for inputs: "eye","race car","not a palindrome","A man, a plan, a canal. Panama","never odd or even"... However, it returns "true" when the input is "almostomla". Can someone please explain why?

function palindrome(str) {

  var newStr = str.replace(/[^0-9a-zA-Z]/g, '');
  newStr = newStr.replace(/\s+/g, '');
  newStr = newStr.toLowerCase();
  var arr = newStr.split('');
  var arr2 =[];

  for(x = 0; x < arr.length; x++){
    arr2.push(arr[arr.length-1-x]);
  }

  for(y = 0; y < arr.length; y++){
    if(arr[y] == arr2[y]){
      return true;
    }
    else{
      return false;
    }
  }

}

palindrome("almostomla");

You are only checking first and last characters in your last for loop.

for(y = 0; y < arr.length; y++){
    if(arr[y] == arr2[y]){ //if first and last chars equal you are returning true.
      return true;
    }
    else{
      return false;
    }
}

You should check all characters until a difference or the end.

for(y = 0; y < arr.length; y++){
    if(arr[y] != arr2[y]){
      return false;
    }
}

return true; --that means two arrays are same.

You can make use a simpler function to check if a word is palindrome:

function checkPalindrom(str) {
    return str == str.split('').reverse().join('');
}

checkPalindrom("almostomla"); // false

I would really replace the palindrome checking function like below, after removing noise:

 function palindrome(str) { var newStr = str.replace(/[^0-9a-zA-Z]/g, ''); newStr = newStr.replace(/\\s+/g, ''); newStr = newStr.toLowerCase(); var arr = newStr.split(''); return arr.join('') == arr.reverse().join(''); } alert(palindrome("almostomla")); alert(palindrome("never odd or even"));

Works as expected.

Why doesn't your old code work?

It checks only the first correct thing and returns true . You should remove the return true from there. Your code is as soon as first and last character are same, consider it as palindrome .

So your code, corrected form will be:

 function palindrome(str) { var newStr = str.replace(/[^0-9a-zA-Z]/g, ''); newStr = newStr.replace(/\\s+/g, ''); newStr = newStr.toLowerCase(); var arr = newStr.split(''); var arr2 = []; for (var x = 0; x < arr.length; x++) { arr2.push(arr[arr.length - 1 - x]); } for (var y = 0; y < arr.length; y++) { debugger; if (arr[y] != arr2[y]) { return false; } } return true; // Place it here to return after the whole loop. } alert(palindrome("almostomla")); alert(palindrome("never odd or even"));

Why not simply do this:

function palindrome(str) {

  var isPalindrome = true;
  var newStr = str.replace(/[^0-9a-zA-Z]/g, '');
  newStr = newStr.replace(/\s+/g, '');
  newStr = newStr.toLowerCase();
  var arr = newStr.split('');

  for(x = 0; x < arr.length / 2; x++) {
      if(arr[x] != arr[arr.length - 1 - x])
      {
          isPalindrome = false;
          break;
      }
  }    

  return isPalindrome;
}

You are returning just after comparing the first entry:

for(y = 0; y < arr.length; y++){
    if(arr[y] == arr2[y]){
      return true; // here you are returning
    }
    else{
      return false;
    }
  }

So in case of almostomla the first element of both arr and arr2 is a because the string starts and ends with a .

You can do it like this to check the first entry which doesn't match:

var flag = true;

  for(y = 0; y < arr.length; y++){
    if(arr[y] != arr2[y]){
      flag= false;
      break;
    }
  }

return flag;

You compare the first and the last letter. If they are the same, then the code returns "True" without checking other letters in the string. The comparisons should continue even though the first iteration of the loop yields "True"!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM