回文检查在 Javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14813369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Palindrome check in Javascript
提问by emcee22
I have the following:
我有以下几点:
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');
What is wrong with my code? I want to check if the word is a palindrome.
我的代码有什么问题?我想检查这个词是否是回文。
回答by dfsq
Maybe I will suggest alternative solution:
也许我会建议替代解决方案:
function checkPalindrom (str) {
return str == str.split('').reverse().join('');
}
UPD. Keep in mind however that this is pretty much "cheating" approach, a demonstration of smart usage of language features, but not the most practical algorithm (time O(n), space O(n)). For real life application or coding interview you should definitely use loop solution. The oneposted by Jason Sebring in this thread is both simple and efficient (time O(n), space O(1)).
更新。但是请记住,这几乎是“欺骗”方法,展示了语言功能的巧妙使用,但不是最实用的算法(时间 O(n),空间 O(n))。对于现实生活中的应用程序或编码面试,您绝对应该使用循环解决方案。在一个由Jason Sebring在这个线程发布既简单又有效的(时间为O(n),空间O(1))。
回答by Jason Sebring
25x faster than the standard answer
比标准答案快 25 倍
function isPalindrome(s,i) {
return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}
use like:
使用像:
isPalindrome('racecar');
as it defines "i" itself
因为它定义了“我”本身
Fiddle: http://jsfiddle.net/namcx0yf/9/
小提琴:http: //jsfiddle.net/namcx0yf/9/
This is ~25 times faster than the standard answer below.
这比下面的标准答案快约 25 倍。
function checkPalindrome(str) {
return str == str.split('').reverse().join('');
}
Fiddle: http://jsfiddle.net/t0zfjfab/2/
小提琴:http: //jsfiddle.net/t0zfjfab/2/
View console for performance results.
查看控制台以获取性能结果。
Although the solution is difficult to read and maintain, I would recommend understanding it to demonstrate non-branching with recursion and bit shifting to impress your next interviewer.
尽管该解决方案难以阅读和维护,但我建议您理解它,以通过递归和位移来展示非分支,从而给您的下一位面试官留下深刻印象。
explained
解释
The || and && are used for control flow like "if" "else". If something left of || is true, it just exits with true. If something is false left of || it must continue. If something left of && is false, it exits as false, if something left of a && is true, it must continue. This is considered "non-branching" as it does not need if-else interupts, rather its just evaluated.
|| 和 && 用于像“if”“else”这样的控制流。如果有东西 || 是真的,它只是以真退出。如果某事是假的离开 || 它必须继续下去。如果 && 剩下的东西是假的,它作为假退出,如果 && 剩下的东西是真的,它必须继续。这被认为是“非分支”,因为它不需要 if-else 中断,而只是对其进行评估。
1.Used an initializer not requiring "i" to be defined as an argument. Assigns "i" to itself if defined, otherwise initialize to 0. Always is false so next OR condition is always evaluated.
1.使用不需要将“i”定义为参数的初始化程序。如果定义,则将“i”分配给自身,否则初始化为 0。Always 为假,因此始终评估下一个 OR 条件。
(i = i || 0) < 0
2.Checks if "i" went half way but skips checking middle odd char. Bit shifted here is like division by 2 but to lowest even neighbor division by 2 result. If true then assumes palindrome since its already done. If false evaluates next OR condition.
2.检查“i”是否走到一半但跳过检查中间的奇数字符。位移位在这里就像除以 2 但到最低的偶数邻居除以 2 结果。如果为真,则假定回文,因为它已经完成。如果 false 评估下一个 OR 条件。
i >= s.length >> 1
3.Compares from beginning char and end char according to "i" eventually to meet as neighbors or neighbor to middle char. If false exits and assumes NOT palindrome. If true continues on to next AND condition.
3.根据“i”从开始字符和结束字符进行比较,最终作为邻居或邻居遇到中间字符。如果 false 退出并假设 NOT 回文。如果 true 继续下一个 AND 条件。
s[i] == s[s.length-1-i]
4.Calls itself again for recursion passing the original string as "s". Since "i" is defined for sure at this point, it is pre-incremented to continue checking the string's position. Returns boolean value indicating if palindrome.
4.再次调用自身进行递归,将原始字符串作为“s”传递。由于“i”在这一点上是确定定义的,因此它被预先增加以继续检查字符串的位置。返回指示是否回文的布尔值。
isPalindrome(s,++i)
BUT...
但...
A simple for loop is still about twice as fast as my fancy answer (aka KISS principle)
一个简单的 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;
}
回答by epascarello
First problem
第一个问题
= is assign == is compare
= 是赋值 == 是比较
Second problem, Your logic here is wrong
第二个问题,你这里的逻辑是错误的
palindrom.charAt(palindrom.length)-1
You are subtracting one from the charAt and not the length.
您是从 charAt 中减去一个而不是长度。
Third problem, it still will be wrong since you are not reducing the length by i.
第三个问题,它仍然是错误的,因为你没有将长度减少 i。
回答by Adolfo Luzardo Cabrera
It works to me
它对我有用
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);
}
回答by Max
SHORTEST CODE (31 chars)(ES6):
最短代码(31 个字符)(ES6):
p=s=>s==[...s].reverse().join``
p('racecar'); //true
Keep in mind short code isn't necessarily the best. Readability and efficiency can matter more.
请记住,短代码不一定是最好的。可读性和效率可能更重要。
回答by BeRecursive
The logic here is not quite correct, you need to check every letter to determine if the word is a palindrome. Currently, you print multiple times. What about doing something like:
这里的逻辑不太正确,需要检查每个字母以确定该单词是否为回文。目前,您打印多次。做这样的事情怎么样:
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");
}
Which should print that it IS indeed a palindrome.
哪个应该打印它确实是一个回文。
回答by Scott Sauyet
At least three things:
至少三件事:
You are trying to test for equality with
=, which is used for setting. You need to test with==or===. (Probably the latter, if you don't have a reason for the former.)You are reporting results after checking each character. But you don't know the results until you've checked enough characters.
You double-check each character-pair, as you really only need to check if, say
first === lastand not also iflast === first.
您正在尝试测试与
=用于设置的相等性。您需要使用==或进行测试===。(可能是后者,如果你没有理由选择前者。)您在检查每个字符后报告结果。但是在检查足够的字符之前,您不知道结果。
你仔细检查每个字符对,因为你真的只需要检查 if , say
first === last而不是 iflast === first。
回答by Wildhoney
As a much clearer recursive function: http://jsfiddle.net/dmz2x117/
作为一个更清晰的递归函数: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(''));
}
回答by Cody
The most important thing to do when solving a Technical Test is Don't use shortcut methods-- they want to see how you think algorithmically! Not your use of methods.
解决技术测试时要做的最重要的事情是不要使用快捷方法——他们想看看你在算法上是如何思考的!不是你使用的方法。
Here is one that I came up with (45 minutes after I blew the test). There are a couple optimizations to make though. When writing any algorithm, its best to assume falseand alter the logic if its looking to be true.
这是我想出的一个(在我完成测试后 45 分钟)。虽然有一些优化。在编写任何算法时,最好假设false并改变逻辑,如果它看起来是true.
isPalindrome():
isPalindrome():
Basically, to make this run in O(N)(linear) complexity you want to have 2 iteratorswhose vectors point towards each other. Meaning, one iterator that starts at the beginning and one that starts at the end, each traveling inward. You could have the iterators traverse the whole array and use a condition to break/returnonce they meet in the middle, but it may save some work to only give each iterator a half-lengthby default.
基本上,要使这个以O(N)(线性)复杂度运行,您需要有 2 个迭代器,它们的向量指向彼此。意思是,一个从头开始的迭代器,一个从最后开始的迭代器,每个都向内移动。您可以让迭代器遍历整个数组并在它们在中间相遇时使用条件 to break/ return,但是默认情况下只给每个迭代器一个半长可能会节省一些工作。
forloops seem to force the use of more checks, so I used whileloops - which I'm less comfortable with.
for循环似乎强制使用更多的检查,所以我使用了while循环 - 我不太舒服。
Here's the code:
这是代码:
/**
* 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);
Notice that if the loops count out, it returns true. All the logic should be inverted so that it by default returns false. I also used one short cut method String.prototype.charAt(n), but I felt OK with this as every language natively supports this method.
请注意,如果循环计数结束,则返回true。应该反转所有逻辑,以便默认情况下返回false. 我还使用了一种捷径方法String.prototype.charAt(n),但我对此感觉还可以,因为每种语言本身都支持这种方法。
回答by Ilian Grekov
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
Finds and upper to lower case. Split string into array, I don't know why a few white spaces remain, but I wanted to catch and single letters.
查找和大写到小写。将字符串拆分为数组,我不知道为什么会保留一些空格,但我想捕获单个字母。

