Я пытаюсь написать код, чтобы определить, является ли строка палиндромом. Я делаю строку строчными буквами, вынимаю пробелы и превращаю ее в массив. Затем я делю его пополам, переворачиваю вторую половину и сравниваю эти два массива, чтобы увидеть, является ли строка палиндромом. Функция не регистрирует истину.
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();
Почему бы просто не проверить, совпадает ли символ в i с символом в length - i - 1, пока не дойдете до половины пути? Кроме того, «Я не уверен что не так» не является достаточным объяснением вашей проблемы, что пошло не так?
Вы пытаетесь сравнить два массива с помощью ===, что у вас не получается. Вам нужно join массивов в две строки и тогда сравнить их.
Однострочный для развлечения: const isPalindrome = s => s.length <= 1 ? true : (s.substr(-1) === s.substr(0, 1) && isPalindrome(s.substr(1, length-2))) Вы можете предварительно обработать строку, чтобы удалить пробелы и верхние буквы.
@ spender - все это можно сделать без рекурсии еще несколькими символами: let isPalindrome = s => s.toLowerCase().replace(/[^a-z0-9]/g,'').split('').every((c, i, o) => c == o[o.length - ++i]), хотя он выполняет примерно в два раза больше тестов, чем требуется минимально. :-)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В этой строке
if (firstHalf === revSecondHalf) {
вы пытаетесь сравнить два массива, но JavaScript не позволяет вам сделать это с ===, поскольку это два разных объекта. Либо join преобразовать каждый массив в строку, а затем сравнить их, либо выполнить цикл по элементам в одном массиве, сравнивая их с элементами с тем же индексом в другом массиве.
Первый способ проще.
Есть гораздо более простой способ сделать это.
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));
Возможный дубликат Проверить строку на палиндром