如何在JavaScript中编写回文字符串

43

我想知道如何在javascript中编写回文程序,输入不同的单词后程序会显示该单词是否是回文。例如,单词“noon”是回文,而“bad”则不是。

提前感谢您。


27
通常要求别人编写检测回文的函数的目的是为了教授编程。如果让别人代劳,你就学不到任何东西。 - Ben
1
这个问题已经被问过并回答了几次 http://stackoverflow.com/a/20662606/437019 - Yossi Shasho
67个回答

2

这个函数将删除所有非字母数字字符(标点、空格和符号),并将所有内容转换为小写,以检查回文。

function palindrome(str){

    var re = /[^A-Za-z0-9]/g;
    str = str.toLowerCase().replace(re, '');
    return str == str.split('').reverse().join('') ? true : false;

}

2

尝试这个

isPalindrome = (string) => {
    if (string === string.split('').reverse().join('')) {
        console.log('is palindrome');
    }
    else {
        console.log('is not palindrome');
    }
}

isPalindrome(string)

2
解决技术测试最重要的事情是不要使用快捷方式--他们想看到你的算法思维,而不是你使用的方法。

这是我想出来的一个(在我失败后的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),但我感觉这样做没问题,因为每种语言都本地支持此方法。

1
这确实需要成为最佳答案。所有其他答案都使用了捷径方法,这不仅不能展示你的算法思维方式,而且也非常低效! - feihcsim
1
@feihcsim,回到这个答案,我注意到我们可以更进一步。如果我们想的话,我们甚至可以消除第二个循环(和使用mid),并在遍历整个数组时将j设置为s.length-i(在i>=j处中断)(尽管它不会影响我们的时间复杂度)。这是我个人现在在测试中编写的方式,但这更多是可读性的问题。另外,似乎我提到了默认返回false,但这里看起来并没有这样做。感谢你的赞美。 - Cody

2

以下是使用ES6功能检查字符串回文的最佳且健壮的解决方案。

最初的回答:

const str="madam"
var result=[...str].reduceRight((c,v)=>((c+v)))==str?"Palindrome":"Not Palindrome";
console.log(result);


1
或者你可以像这样做。
var palindrome = word => word == word.split('').reverse().join('')

1
像这个答案一样,也可以这样写:const palindrome = word => word == [...word].reverse().join('') - Hamzeen Hameem

1
这个怎么样?
function pall (word) {

    var lowerCWord = word.toLowerCase();
    var rev = lowerCWord.split('').reverse().join('');

    return rev.startsWith(lowerCWord);
    }

pall('Madam');

1

25倍速 + 递归 + 非分支 + 简洁

function isPalindrome(s,i) {
 return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}

在此处查看我的完整解释。


1

这段代码简洁、快速且易于理解。

简述:

解释:这里的isPalindrome函数接受一个字符串类型的str参数。

  1. If the length of the str param is less than or equal to one it simply returns "false".
  2. If the above case is false then it moves on to the second if statement and checks that if the character at 0 position of the string is same as character at the last place. It does an inequality test between the both.

    str.charAt(0)  // gives us the value of character in string at position 0
    str.slice(-1)  // gives us the value of last character in the string.
    
如果不等式成立,则继续执行并返回false。
如果前面语句的结果为false,则会递归调用isPalindrome(str)函数,直到得出最终结果。

 function isPalindrome(str){
 
 if (str.length <= 1) return true;
 if (str.charAt(0) != str.slice(-1)) return false;
 return isPalindrome(str.substring(1,str.length-1));
 };


document.getElementById('submit').addEventListener('click',function(){
 var str = prompt('whats the string?');
 alert(isPalindrome(str))
});

document.getElementById('ispdrm').onsubmit = function(){alert(isPalindrome(document.getElementById('inputTxt').value));
}
<!DOCTYPE html>
<html>
<body>
<form id='ispdrm'><input type="text" id="inputTxt"></form>

<button id="submit">Click me</button>
</body>
</html>


1
function palindrome(str) {
    var lenMinusOne = str.length - 1;
    var halfLen = Math.floor(str.length / 2);

    for (var i = 0; i < halfLen; ++i) {
        if (str[i] != str[lenMinusOne - i]) {
            return false;
        }
    }
    return true;
}

针对半字符串解析和常量值变量进行优化。


不,你说得对,它不像C语言那样四舍五入,是我的错。不过,在我的设置中,这个算法比被接受的答案快两倍。 - neural5torm
1
这里的许多答案都是迭代整个字符串而不是一半,或者使用完整字符串进行镜像测试而不是使用一半。人群的集体智慧尚未意识到这一点。 :-) - mvw
我的回答的重点是与“reverse”函数回文有所区别,在你的答案中算法仍然相同。无论如何,做得很好 :) - nanobash
我理解,但既然你的赏金是关于性能效率的,我认为将计算减少一半并不是一个坏的改进。 ;) - neural5torm
虽然我的答案和reverse的答案不同,但这里的所有答案都是一样的。我故意没有将字符串长度分为两个部分,而是使它更大,以便使用标记算法来区分时间上的差异。 - nanobash
显示剩余2条评论

1
我认为以下时间复杂度为o(log n)的函数会更好。
    function palindrom(s){
    s = s.toString();
    var f = true; l = s.length/2, len = s.length -1;
    for(var i=0; i < l; i++){
            if(s[i] != s[len - i]){
                    f = false; 
                    break;
            }
    }
    return f;

    }

console.log(palindrom(12321));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接