Палиндром в JavaScript

Я пытаюсь написать код, чтобы определить, является ли строка палиндромом. Я делаю строку строчными буквами, вынимаю пробелы и превращаю ее в массив. Затем я делю его пополам, переворачиваю вторую половину и сравниваю эти два массива, чтобы увидеть, является ли строка палиндромом. Функция не регистрирует истину.

let string = "Never odd or even";
let lowerString = string.toLowerCase();
let split = lowerString.split("");
let array = split.filter(noSpaces);

function noSpaces(i) {
  return i !== " ";
}

function checkIfPal() {
  if (array.length % 2 === 1) {
    let firstHalf = array.slice(0, array.length / 2);
    let secondHalf = array.slice(array.length / 2 + 1, array.length);
    let revSecondHalf = [];
    for (let i = secondHalf.length - 1; i > -1; i--) {
      revSecondHalf.push(secondHalf[i]);
    }
    if (firstHalf === revSecondHalf) {
      console.info("true for odd");
    } else {
      console.info("false for odd");
    }
  } else {
    let firstHalf = array.slice(0, array.length / 2);
    let secondHalf = array.slice(array.length / 2, array.length);
    let revSecondHalf = [];
    for (let i = secondHalf.length - 1; i > -1; i--) {
      revSecondHalf.push(secondHalf[i]);
    }
    if (firstHalf === revSecondHalf) {
      console.info("true for even");
    } else {
      console.info("false for even");
    }
  }
}
checkIfPal();

Возможный дубликат Проверить строку на палиндром

Akrion 22.11.2018 01:28

Почему бы просто не проверить, совпадает ли символ в i с символом в length - i - 1, пока не дойдете до половины пути? Кроме того, «Я не уверен что не так» не является достаточным объяснением вашей проблемы, что пошло не так?

RobG 22.11.2018 01:30

Вы пытаетесь сравнить два массива с помощью ===, что у вас не получается. Вам нужно join массивов в две строки и тогда сравнить их.

Andy 22.11.2018 01:32
stackoverflow.com/questions/7837456/…
epascarello 22.11.2018 01:35

Однострочный для развлечения: const isPalindrome = s => s.length <= 1 ? true : (s.substr(-1) === s.substr(0, 1) && isPalindrome(s.substr(1, length-2))) Вы можете предварительно обработать строку, чтобы удалить пробелы и верхние буквы.

spender 22.11.2018 01:59

@ spender - все это можно сделать без рекурсии еще несколькими символами: let isPalindrome = s => s.toLowerCase().replace(/[^a-z0-9]/g,'').split('').every((c, i, o) => c == o[o.length - ++i]), хотя он выполняет примерно в два раза больше тестов, чем требуется минимально. :-)

RobG 22.11.2018 10:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
6
967
4

Ответы 4

В этой строке

if (firstHalf === revSecondHalf) {

вы пытаетесь сравнить два массива, но JavaScript не позволяет вам сделать это с ===, поскольку это два разных объекта. Либо join преобразовать каждый массив в строку, а затем сравнить их, либо выполнить цикл по элементам в одном массиве, сравнивая их с элементами с тем же индексом в другом массиве.

Первый способ проще.

Есть гораздо более простой способ сделать это.

  1. Вычеркните все, что не является буквой или цифрой
  2. Сделайте строку в нижнем регистре
  3. Оберните половину струны
  4. Сравнить текущую букву с последней буквой минус текущая позиция

function isPalindrome(str) {
    str = str.replace(/[^\w\d]/g, '').toLowerCase();
    const len = str.length;

    for (let i = 0; i < len / 2; i++) {
        if (str[i] !== str[len - 1 - i]) {
            return false;
        }
    }

    return true;
}

console.info(isPalindrome('A man, a plan, a canal, Panama!'));
console.info(isPalindrome('Mr. Owl Ate My Metal Worm'));
console.info(isPalindrome('A Santa Lived As a Devil At NASA'));

И еще есть очень простой, но не очень эффективный способ сделать это на длинных струнах.

function isPalindrome(str) {
    str = str.replace(/[^\w\d]/g, '').toLowerCase();
    return str === str.split('').reverse().join('');
}

console.info(isPalindrome('A man, a plan, a canal, Panama!'));
console.info(isPalindrome('Mr. Owl Ate My Metal Worm'));
console.info(isPalindrome('A Santa Lived As a Devil At NASA'));

В вашем скрипте вы сравниваете два объекта массива друг с другом с помощью ===.

Если переменные в сравнении ссылаются на один и тот же объект массива, тогда будет возвращен true. Но если они указывают на два разных объекта массива, даже если их содержимое одинаково, он всегда будет возвращать false.

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

function compareArrayElements(arr1, arr2) {
    if (arr1.length != arr2.length)
        return false;
    for (var i=0;i<arr1.length;i++) {
        if (arr1[i] != arr2[i])
            return false;
    }
    return true;
}

Теперь, когда у вас есть решение, вы можете работать над его оптимизацией и уменьшением количества циклов for.

Алгоритм на основе сравнение массива с его реверсом:

const isPalindrome = (str) => {
  //Eliminate punctuation and spaces
  // Force lower case
  // Split
   let arr = str.toString().replace(/[^A-Za-z0-9_]/g, "").toLowerCase().split('');

  // Join into one word
  let joined = arr.join('');

  // Reverse adn join into one word
  let reverseJoined = arr.reverse().join('');

  //compare
  return joined == reverseJoined;
}

console.info(isPalindrome('Red rum, sir, is murder'));
console.info(isPalindrome(404));
console.info(isPalindrome('Red rum, sir'));
console.info(isPalindrome(500));

Другие вопросы по теме