回文检查在 Javascript

IT技术 javascript
2021-02-08 17:21:45

我有以下几点:

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

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

6个回答

也许我会建议替代解决方案:

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

更新。但是请记住,这几乎是“欺骗”方法,展示了语言功能的巧妙使用,但不是最实用的算法(时间 O(n),空间 O(n))。对于现实生活中的应用程序或编码面试,您绝对应该使用循环解决方案。一个由Jason Sebring在这个线程发布既简单又有效的(时间为O(n),空间O(1))。

这显然是最简单的代码,尽管可能不是最有效的解决方案但是对于像原始代码那样编写代码的人来说,也许朝着好的解决方案更简单的步骤比朝着好的解决方案飞跃更有帮助?
2021-03-12 17:21:45
你说的对。我的变体不是教 OP 如何编程(还有其他 5 个与这个原始问题更相关的好答案),我只是展示了解决问题的不同方法。而发明非显而易见方式的能力也很重要。
2021-03-14 17:21:45
@HamzaBahlaouane 最简单的方法是在运行比较之前使用 .toLowerCase(或 .toUpperCase)以及删除有问题的字符的正则表达式。所以,在第 2 行之前,添加类似str = str.toLowerCase().replace( /[\s~`!@#$%^&*()-_+=[\]{}\\|:;"',<>.?\/\u2000-\u206F\u2E00-\u2E7F\u3000-\u303F]/g, '');或者,如果你不关心 Unicode 支持,str = str.toLowerCase().replace(/\W/g, '')
2021-03-28 17:21:45
revString("eye") => true while revString("race car") => false 而回文是向前和向后拼写相同的单词或句子,忽略标点符号、大小写和空格。我们如何改进这一点?
2021-04-07 17:21:45
如果字符串有空格或标点符号,你需要一些额外的代码,仅供参考
2021-04-10 17:21:45

比标准答案快 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/

查看控制台以获取性能结果。

尽管该解决方案难以阅读和维护,但我建议您理解它,以通过递归和位移来展示非分支,从而给您的下一位面试官留下深刻印象。

解释

|| 和 && 用于像“if”“else”这样的控制流。如果有东西 || 是真的,它只是以真退出。如果某事是假的离开 || 它必须继续下去。如果 && 剩下的东西是假的,它作为假退出,如果 && 剩下的东西是真的,它必须继续。这被认为是“非分支”,因为它不需要 if-else 中断,而只是对其进行评估。

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

(i = i || 0) < 0

2.检查“i”是否走到一半但跳过检查中间的奇数字符。位移位在这里就像除以 2 但到最低的偶数邻居除以 2 结果。如果为真,则假定回文,因为它已经完成。如果 false 评估下一个 OR 条件。

i >= s.length >> 1

3.根据“i”从开始字符和结束字符进行比较,最终作为邻居或邻居遇到中间字符。如果 false 退出并假定 NOT 回文。如果 true 继续下一个 AND 条件。

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

4.再次调用自身进行递归,将原始字符串作为“s”传递。由于“i”在这一点上是确定定义的,因此它被预先增加以继续检查字符串的位置。返回指示是否回文的布尔值。

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/

丑25倍
2021-03-12 17:21:45
isPalindrome('Avid diva'.toLowerCase())返回true
2021-03-23 17:21:45
是的,我应该澄清一下,它非常狡猾,而且超出了我的头脑:)
2021-03-25 17:21:45
@ChrisHawkes 我100% 同意。重点是对语言特性进行教育,并在底部提供一点,表明纯编程既快速又易于查看。
2021-03-31 17:21:45
这将返回错误: console.log(isPalindrome('Avid diva'));
2021-04-03 17:21:45

第一个问题

= 是赋值 == 是比较

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

palindrom.charAt(palindrom.length)-1

您是从 charAt 中减去一个而不是长度。

第三个问题,它仍然是错误的,因为你没有将长度减少 i。

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

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

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

@MG_Bautista 都做不同的事情,就像=====
2021-03-22 17:21:45
!== 对不等式进行类型检查,在 Javascript 中,始终使用类型检查运算符通常是一种很好的做法。
2021-03-25 17:21:45
@AndyE 同意,我在尝试加快速度方面疏忽了
2021-04-01 17:21:45
i < word.length / 2顺便说一句,您可能想要,因为在单词中途之后的任何迭代都是多余的。
2021-04-04 17:21:45
它的方式是,if (checkPalindrome("Avid diva")) {将打印:The word is NOT a palindrome您需要强制lowercase覆盖带有大写字母的单词......word = word.toLowerCase()希望它有所 帮助。
2021-04-05 17:21:45

它对我有用

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