Подтвердить что ты не робот

Проверка палиндрома в Javascript

i имеет следующее:

function checkPalindrom(palindrom)
{

    for( var i = palindrom.length; i > 0; i-- )
    {
        if( palindrom[i] = palindrom.charAt(palindrom.length)-1 )
        {
            document.write('the word is palindrome.');
        }else{
            document.write('the word is not palindrome!');
        }
    }
}
checkPalindrom('wordthatwillbechecked');

Что не так с моим кодом? Я хочу проверить, является ли слово палиндром.

4b9b3361

Ответ 1

Может быть, я предложу альтернативное решение:

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

UPD. Имейте в виду, однако, что это в значительной степени "читерский" подход, демонстрация умного использования языковых возможностей, но не самый практичный алгоритм (время O (n), пространство O (n)). Для реальных приложений или собеседований по кодированию вы должны обязательно использовать циклическое решение. Один отправленный Джейсон Sebring в этой теме является простым и эффективным (время О (п), пространство O (1)).

Ответ 2

25 раз быстрее, чем стандартный ответ

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

используйте как:

isPalindrome('racecar');

поскольку он сам определяет "i"

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

Это примерно в 25 раз быстрее, чем стандартный ответ ниже.

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

Fiddle: http://jsfiddle.net/t0zfjfab/2/

Просмотрите консоль для получения результатов.

Несмотря на то, что решение трудно читать и поддерживать, я бы рекомендовал понять его, чтобы продемонстрировать не ветвление с рекурсией и смещением битов, чтобы произвести впечатление на вашего следующего интервьюера.

объяснил

|| и && используются для управления потоком, как "if" "else". Если что-то осталось от || это правда, он просто выходит с истиной. Если что-то ложно слева || он должен продолжаться. Если что-то осталось от && false, он выходит как ложный, если что-то осталось от && это правда, оно должно продолжаться. Это считается "не ветвящимся", поскольку он не нужен, если-else перехватывает, а просто оценивается.

1. Используется инициализатор, не требующий определения "i" в качестве аргумента. Присваивает "i" себе, если он определен, иначе инициализируется значение 0. Всегда является false, поэтому следующее условие OR всегда оценивается.

(i = i || 0) < 0

2. Проверяет, прошел ли "i" на полпути, но пропускает проверку среднего значения char. Бит сдвигается здесь, как деление на 2, но на низшее даже соседнее деление на 2 результат. Если true, то предполагает палиндром с момента его выполнения. Если false оценивает следующее условие ИЛИ.

i >= s.length >> 1

3. Сравнивает с начала char и заканчивает char в соответствии с "i" в конце концов, чтобы встретиться как соседи или соседи со средним char. Если false выходит и не принимает палиндрома. Если истина продолжается до следующего условия И.

s[i] == s[s.length-1-i]

4. снова вызывает себя для рекурсии, передавая исходную строку как "s". Поскольку "i" определен точно в этот момент, он предварительно увеличивается, чтобы продолжить проверку позиции строки. Возвращает логическое значение, указывающее, является ли палиндром.

isPalindrome(s,++i)

Но...

Простая для цикла все еще примерно в два раза быстрее, чем мой причудливый ответ ( или принцип KISS)

function fastestIsPalindrome(str) {
  var len = Math.floor(str.length / 2);
  for (var i = 0; i < len; i++)
    if (str[i] !== str[str.length - i - 1])
      return false;
  return true;
}

http://jsfiddle.net/6L953awz/1/

Ответ 3

Первая проблема

= присваивается == сравнивает

Вторая проблема. Ваша логика здесь неверна.

palindrom.charAt(palindrom.length)-1

Вы вычитаете один из charAt, а не длину.

Третья проблема, она по-прежнему будет неправильной, так как вы не уменьшаете длину на i.

Ответ 4

Это работает для меня

function palindrome(str) {
  /* remove special characters, spaces and make lowercase*/
  var removeChar = str.replace(/[^A-Z0-9]/ig, "").toLowerCase();

  /* reverse removeChar for comparison*/
  var checkPalindrome = removeChar.split('').reverse().join('');

  /* Check to see if str is a Palindrome*/
   return (removeChar === checkPalindrome);
}

Ответ 5

Логика здесь не совсем правильная, вам нужно проверить каждую букву, чтобы определить, является ли это слово палиндром. В настоящее время вы печатаете несколько раз. Как сделать что-то вроде:

function checkPalindrome(word) {    
    var l = word.length;
    for (var i = 0; i < l / 2; i++) {
        if (word.charAt(i) !== word.charAt(l - 1 - i)) {
            return false;
        }
    }
    return true;
}

if (checkPalindrome("1122332211")) {
    document.write("The word is a palindrome");
} else {
    document.write("The word is NOT a palindrome");
}

Что должно печатать, что это действительно палиндром.

Ответ 6

Кратчайший код (31 символ) (ES6):

p=s=>s==[...s].reverse().join''
p('racecar'); //true

Имейте в виду, что короткий код не обязательно лучший. Читабельность и эффективность могут иметь большее значение.

Ответ 7

Как минимум три вещи:

  • Вы пытаетесь проверить соответствие с =, которое используется для установки. Тестировать нужно с помощью == или ===. (Возможно, последнее, если у вас нет причины для первого.)

  • Вы сообщаете результаты после проверки каждого символа. Но вы не знаете результатов, пока не проверите достаточно символов.

  • Вы дважды проверяете каждую пару символов, так как вам действительно нужно только проверить, скажите first === last, а также если last === first.

Ответ 8

Как более ясная рекурсивная функция: http://jsfiddle.net/dmz2x117/

function isPalindrome(letters) {

    var characters  = letters.split(''),
        firstLetter = characters.shift(),
        lastLetter  = characters.pop();

    if (firstLetter !== lastLetter) {
        return false;
    }

    if (characters.length < 2) {
        return true;
    }

    return isPalindrome(characters.join(''));

}

Ответ 9

Самое главное, что нужно сделать при техническом тестировании, - Не использовать методы быстрого доступа - , они хотят видеть, как вы думаете алгоритмически! Не использование методов.

Вот один, который я придумал (через 45 минут после того, как я взорвал тест). Однако есть пара оптимизаций. При написании любого алгоритма лучше всего принять false и изменить логику, если она выглядит как true.

isPalindrome():

В принципе, чтобы выполнить этот прогон в O (N) (линейной) сложности, вы хотите иметь 2 итератора, векторы которых указывают друг на друга. Значение, один итератор, который начинается в начале и один, который начинается в конце, каждый из которых перемещается внутрь. Вы могли бы заставить итераторы пересекать весь массив и использовать условие для break/return, когда они встречаются посередине, но это может сэкономить некоторую работу, чтобы по умолчанию дать каждому итератору половину длины.

Циклы

for, похоже, заставляют использовать больше проверок, поэтому я использовал while петли - что мне менее удобно.

Здесь код:

/**
 * TODO: If func counts out, let it return 0
 *  * Assume !isPalindrome (invert logic)
 */
function isPalindrome(S){
    var s = S
      , len = s.length
      , mid = len/2;
      , i = 0, j = len-1;

    while(i<mid){
        var l = s.charAt(i);
        while(j>=mid){
            var r = s.charAt(j);
            if(l === r){
                console.log('@while *', i, l, '...', j, r);
                --j;
                break;
            }
            console.log('@while !', i, l, '...', j, r);
            return 0;
        }
        ++i;
    }
    return 1;
}

var nooe = solution('neveroddoreven');  // even char length
var kayak = solution('kayak');  // odd char length
var kayaks = solution('kayaks');

console.log('@isPalindrome', nooe, kayak, kayaks);

Обратите внимание, что если циклы подсчитываются, возвращается true. Вся логика должна быть инвертирована так, чтобы она по умолчанию возвращала false. Я также использовал один метод коротких выкроек String.prototype.charAt(n), но я чувствовал себя хорошо с этим, поскольку каждый язык поддерживает этот метод.

Ответ 10

function palindromCheck(str) {
    var palinArr, i,
        palindrom = [],

    palinArr = str.split(/[\s!.?,;:'"-()]/ig);

    for (i = 0; i < palinArr.length; i++) {
        if (palinArr[i].toLowerCase() === palinArr[i].split('').reverse().join('').toLowerCase() &&
            palinArr[i] !== '') {
            palindrom.push(palinArr[i]);
        }
    }
        return palindrom.join(', ');
}
console.log(palindromCheck('There is a man, his name! was Bob.')); //a, Bob

Находит и от верхнего к нижнему регистру. Разделите строку на массив, я не знаю, почему осталось несколько белых пробелов, но я хотел поймать и выделить буквы.

Ответ 11

  • = в palindrom[i] = palindrom.charAt(palindrom.length)-1 должен быть == или ===
  • palindrom.charAt(palindrom.length)-1 должен быть palindrom.charAt(palindrom.length - i)

Ответ 12

function checkPalindrom(palindrom)
{
   var flag = true;
   var j = 0;
    for( var i = palindrom.length-1; i > palindrom.length / 2; i-- )
    {
        if( palindrom[i] != palindrom[j] )
        {
           flag = false;
           break; // why this? It'll exit the loop at once when there is a mismatch.
        }
        j++;
    }
  if( flag ) {
  document.write('the word is palindrome.');
  }
  else {
document.write('the word is not palindrome.');
  }
}
checkPalindrom('wordthatwillbechecked');

Почему я печатаю результат вне цикла? В противном случае, для каждого совпадения в слове, он будет печатать "is or not pallindrome", а не проверять все слово.

EDIT: Обновлено с изменениями и исправлением, предложенным Basemm.

Ответ 13

Я добавил еще кое-что к вышеперечисленным функциям, чтобы проверить строки вроде: "Пойдите, вешайте салями, я - лазаньон-боров".

function checkPalindrom(str) {
    var str = str.replace(/[^a-zA-Z0-9]+/gi, '').toLowerCase();
    return str == str.split('').reverse().join('');
}

Спасибо

Ответ 14

Обмен моим быстрым вариантом, который также поддерживает пробелы

function isPalindrom(str) {
  var ia = 0;
  var ib = str.length - 1;
  do {
    if (str[ia] === str[ib]) continue;

    // if spaces skip & retry
    if (str[ia] === ' ' && ib++) continue;
    if (str[ib] === ' ' && ia--) continue;

    return false;
  } while (++ia < --ib);
  return true;
}
var palindrom="never odd or even";
var res = isPalindrom(palindrom);
document.getElementById('check').innerHTML ='"'+ palindrom + '"'+" checked to be :" +res;
<span id="check" />

Ответ 15

function checkPalindrom(palindrom)
{
  palindrom= palindrom.toLowerCase();
   var flag = true;
   var j;
   j = (palindrom.length) -1 ;
   //console.log(j);
   var cnt = j / 2;
   //console.log(cnt);
    for( i = 0; i < cnt+1 ; i++,j-- )
    {
        console.log("J is => "+j);
        console.log(palindrom[i] + "<==>" + palindrom[j]);
        if( palindrom[i] != palindrom[j] )
        {
           flag = false;
           break; 
        }


    }
  if( flag ) {
  console.log('the word is palindrome.');
  }
  else {
console.log('the word is not palindrome.');
  }
}
checkPalindrom('Avid diva');

Ответ 16

Мне интересно, почему никто не предложил это:

ES6:

// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
isPalindrom = (str = "") => {
  if (str[0] === str[str.length - 1]) {
    return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
  }

  return false;
}

alert(["aba", "acb", "aa", "abba", "s"].map((e, i) => isPalindrom(e)).join())

ES5:

// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
function isPalindrom(str) => {
  var str = typeof str !== "string" ? "" : str;

  if (str[0] === str[str.length - 1]) {
    return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
  }

  return false;
}

alert(["aba", "acb", "aa", "abba", "s"].map(function (e, i) {
    return isPalindrom(e);
}).join());

Ответ 17

Рекурсивный метод:

var low;
var high;
var A = "abcdcba";  

function palindrome(A , low, high){
  A = A.split('');

 if((low > high) || (low == high)){
   return true;
 }

 if(A[low] === A[high]){
   A = A.join('');
   low = low + 1; 
   high = high - 1; 
   return palindrome(A , low, high);
 }
 else{
   return "not a palindrome";
 }
}

palindrome(A, 0, A.length-1);

Ответ 18

Я решил поделиться своим решением:

function palindrome(string){
    var reverseString = '';
    for(var k in string){
       reverseString += string[(string.length - k) - 1];
    }
  if(string === reverseString){
    console.log('Hey there palindrome');
  }else{
    console.log('You are not a palindrome');
  }
}
palindrome('ana');

Ответ 19

Некоторые из вышеприведенных коротких андерсеров хороши, но это нелегко понять, я предлагаю еще один способ:

function checkPalindrome(inputString) {

    if(inputString.length == 1){
        return true;
    }else{
        var i = 0;
        var j = inputString.length -1;
        while(i < j){
            if(inputString[i] != inputString[j]){
                return false;
            }
            i++;
            j--;
        }
    }
    return true;
}

Я сравниваю каждый символ, i start form left, j start from right, пока их индекс не будет действительным (i<j). Он также работает на любых языках

Ответ 20

Я нашел это на сайте интервью:

Напишите эффективную функцию, которая проверяет, была ли какая-либо перестановка входная строка - это палиндром. Вы можете игнорировать пунктуацию, мы только заботимся о персонажах.

Играя с этим, я придумал этот уродливый фрагмент кода:)

function checkIfPalindrome(text) {
    var found = {};
    var foundOne = 0;
    text = text.replace(/[^a-z0-9]/gi, '').toLowerCase();
    for (var i = 0; i < text.length; i++) {
        if (found[text[i]]) {
            found[text[i]]++;
        } else {
            found[text[i]] = 1;
        }
    }
    for (var x in found) {
        if (found[x] === 1) {
            foundOne++;
            if (foundOne > 1) {
                return false;
            }
        }
    }
    for (var x in found) {
        if (found[x] > 2 && found[x] % 2 && foundOne) {
            return false;
        }
    }
    return true;
}

Просто оставим его здесь для потомков.

Ответ 21

Как насчет этого, используя простой флаг

function checkPalindrom(str){
   var flag = true;
   for( var i = 0; i <= str.length-1; i++){
    if( str[i] !== str[str.length - i-1]){
      flag = false;  
     }
    }
    if(flag == false){
      console.log('the word is not a palindrome!');   
    }
    else{
    console.log('the word is a palindrome!');
    }
}

checkPalindrom('abcdcba');

Ответ 22

(JavaScript) С помощью regexp это проверяет буквенно-цифровой палиндром и игнорирует пробел и пунктуацию.

function palindrome(str) {
  str = str.match(/[A-Za-z0-9]/gi).join("").toLowerCase();
  //  (/[A-Za-z0-9]/gi) above makes str alphanumeric

  for(var i = 0; i < Math.floor(str.length/2); i++) { //only need to run for half the string length 
    if(str.charAt(i) !== str.charAt(str.length-i-1)) { // uses !== to compare characters one-by-one from the beginning and end
      return "Try again.";
    }
  }
  return "Palindrome!";
}
palindrome("A man, a plan, a canal. Panama.");
//palindrome("4_2 (: /-\ :) 2-4"); // This solution would also work on something like this.

Ответ 23

Прокрутите строки символов вперед (i) и назад (j), используя цикл for. Если в любой точке символ в str[i] не равен str[j] - тогда это не палиндром. Если мы успешно прокручиваем строку, то это палиндром.

function isPalindrome(str) {
  var valid = true;

  for(var i = 0, j = str.length - 1; i < str.length; i++, j--) {
    if (str[i] !== str[j]) valid = false; break;
  }

  return valid;
}

Ответ 24

`
function checkPalindrome (str) {
    var str = str.toLowerCase();
    var original = str.split(' ').join('');
    var reversed = original.split(' ').reverse().join('');

  return (original === reversed);
}
`

Ответ 25

Это позволяет избежать регулярного выражения, также имея дело со строками с пробелами и прописными буквами...

function isPalindrome(str) {
    str = str.split("");

    var str2 = str.filter(function(x){ 
        if(x !== ' ' && x !== ',') {
            return x;
        }
    });

    return console.log(str2.join('').toLowerCase()) == console.log(str2.reverse().join('').toLowerCase());
};

isPalindrome("A car, a man, a maraca"); //true

Ответ 26

Использование рекурсии:

function isPalindromeRecursive(str) {
  const isLessThan2 = str.length < 2;
  const firstAndLastEqual = str.slice(0, 1) === str.slice(-1);
  return !isLessThan2 && firstAndLastEqual 
    ? isPalindromeRecursive(str.slice(1, -1)) 
    : isLessThan2;
}

Ответ 27

function myPolidrome(polidrome){
 var string=polidrome.split('').join(',');
 for(var i=0;i<string.length;i++){
    if(string.length==1){
     console.log("is polidrome");
   }else if(string[i]!=string.charAt(string.length-1)){
     console.log("is not polidrome");
     break;
  }else{
     return  myPolidrome(polidrome.substring(1,polidrome.length-1));
  }
  }
  }
myPolidrome("asasdsdsa");

Ответ 28

Думаю, я поделюсь своим решением, используя Array.prototype.filter(). фильтр() фильтрует массив на основе логических значений, возвращаемых функцией.

var inputArray=["","a","ab","aba","abab","ababa"]
var outputArray=inputArray.filter(function isPalindrome(x){
  if (x.length<2) return true;
  var y=x.split("").reverse().join("");
  return x==y;
})
console.log(outputArray);

Ответ 29

Это сработало для меня.

var number = 8008
number = number + "";
numberreverse = number.split("").reverse().join('');
console.log ("The number if reversed is: " +numberreverse);
if (number == numberreverse)
    console.log("Yes, this is a palindrome");
else
    console.log("Nope! It isnt a palindrome");

Ответ 30

Вот решение, которое работает, даже если строка содержит не буквенно-цифровые символы.

function isPalindrome(str) {
    str = str.toLowerCase().replace(/\W+|_/g, '');
    return str == str.split('').reverse().join('');
}