回文检查在Javascript

我有以下几点:

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'); 

我的代码有什么问题? 我想检查一下这个词是否是回文。

也许我会build议可能更好的解决scheme:

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

比标准答案快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'); 

因为它定义了“我”本身

小提琴: http : //jsfiddle.net/namcx0yf/9/

这比下面的标准答案快了25倍。

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

小提琴: http : //jsfiddle.net/t0zfjfab/2/

查看控制台的性能结果。

虽然解决scheme很难阅读和维护,但我build议您理解它,以展示非recursion和移位来打动您的下一位面试官。

解释

|| 和&&用于“if”“else”等控制stream程。 如果有什么遗漏的话 是真的,它只是真实地退出。 如果有什么是虚假的|| 它必须继续。 如果&&的剩余部分是错误的,它将作为错误退出,如果&&的剩余部分为真,则必须继续。 这被认为是“非分支”,因为它不需要if-else中断,而只是被评估。

1.使用一个不需要“i”的初始化方法作为参数。 如果已定义,则将“i”分配给自身,否则将初始化为0.始终为假,以便始终评估下一个OR条件。

 (i = i || 0) < 0 

2.检查“我”是否走了一半,但跳过检查中间奇怪的字符。 这里移位的位是2除法,而是2位结果的最低偶平均除法。 如果是真的,那么假设回文已经完成。 如果错误评估下一个OR条件。

 i >= s.length >> 1 

3.根据“我”最终作为邻居或邻居与中间字符相遇,从最初的字符和结束字符相比较。 如果错误退出并且假设没有回文。 如果真的继续下一个AND条件。

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

4.再次调用自身,将原始string传递为“s”。 由于“i”在这一点上被定义为肯定的,所以它是预先递增的以继续检查string的位置。 返回指示回文的布尔值。

 isPalindrome(s,++i) 

但…

一个简单的for循环仍然是我想象的答案的两倍( 又称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/

第一个问题

= is assign ==是比较

第二个问题,你的逻辑是错误的

 palindrom.charAt(palindrom.length)-1 

你正在从charAt减去一个,而不是长度。

第三个问题,由于你没有缩短我的长度,所以这仍然是错误的。

它适用于我

 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); } 

这里的逻辑是不正确的,你需要检查每个字母,以确定该单词是否是回文。 目前,您打印多次。 怎么样做这样的事情:

 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"); } 

哪个应该打印,它确实是一个回文。

至less有三件事情:

  • 您正在尝试使用=来testing是否相等,用于设置。 您需要使用=====进行testing。 (可能后者,如果你没有前者的理由)。

  • 您在检查每个字符后报告结果。 但是,只有检查了足够多的字符,才能知道结果。

  • 你仔细检查每个字符对,因为你真的只需要检查,如果first === last而不是如果last === first

作为一个更清晰的recursion函数: 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('')); } 

最短代码(31个字符)(ES6):

 p=s=>s==[...s].reverse().join`` p('racecar'); //true 
  • =palindrom[i] = palindrom.charAt(palindrom.length)-1应该是=====
  • palindrom.charAt(palindrom.length)-1应该是palindrom.charAt(palindrom.length - i)

解决技术testing时最重要的事情就是不要使用捷径方法他们希望看到你如何思考algorithm! 不是你使用的方法。

这是我提出的一个(在我testing之后的45分钟)。 虽然有几个优化。 在编写任何algorithm时,如果它看起来是true ,最好假设为false并改变逻辑。

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) ,但是我觉得好,因为每种语言都支持这种方法。

 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 

查找和大写小写。 将string拆分成数组,我不知道为什么还留有一些空格,但我想捕捉单个字母。

 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'); 

为什么我在循环之外打印结果? 否则,对于单词中的每一个匹配,它都会打印“是或者不是pallindrome”而不是检查整个单词。

编辑:更新与Basemmbuild议的更改和修复。

我已经添加了一些更多的上述function,检查string,如“去挂香肠,我是烤宽面条猪”。

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

谢谢

我想知道为什么没有人提出这样的build议:

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()); 

recursion方法:

 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); 

分享我的快速变体也支持空格

 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" /> 
 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'); 

我在一个采访网站上find了这个:

编写一个有效的函数来检查inputstring的排列是否是回文。 你可以忽略标点符号,我们只关心字符。

玩弄它,我想出了这个丑陋的代码:)

 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; } 

只是把它留在这里为后人。

怎么样,使用一个简单的标志

 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'); 

(JavaScript)使用正则expression式,这将检查字母数字回文并忽略空格和标点符号。

 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. 

我以为我会分享我自己的解决scheme:

 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'); 

通过string循环使用for循环向前(i)和向后(j)。 如果str[i]中的字符在任何时候都不等于str[j] ,那么它就不是回文。 如果我们成功地通过string,那么它是一个回文。

 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; } 
 ` function checkPalindrome (str) { var str = str.toLowerCase(); var original = str.split(' ').join(''); var reversed = original.split(' ').reverse().join(''); return (original === reversed); } ` 

这避免了正则expression式,同时也处理string有空格和大写…

 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 
 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"); 

以为我会分享我的解决scheme使用Array.prototype.filter()。 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); 

这对我有效。

 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"); 

即使string包含非字母数字字符,这也是一种解决scheme。

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

使用recursion:

 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; } 
 function palindrome(str) { // Good luck! //convert the string into lowerCase. str = str.toLowerCase(); //this line remove all non=alphanumeric characters. strAlphaNum = str.replace(/[^a-z0-9]/g,""); //this line create an array of the strAlphaNum string. strArray = strAlphaNum.split(""); //this line reverse the array strReversed = strArray.reverse(); //this line join the reversed array to make a string whithout space. strRevJoin = strReversed.join(""); //this condition check if the given string is a palindrome. if (strAlphaNum === strRevJoin){ return true;} else {return false;} }