Проверка палиндрома в 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');
Что не так с моим кодом? Я хочу проверить, является ли слово палиндром.
Ответы
Ответ 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('');
}