使用JavaScript进行递归回文检查

6
我尝试使用javascript递归来判断字符串是否是回文。但我无法弄清楚代码中缺少了什么。
var firstCharacter = function(str) {
    return str.slice(0, 1);
};

var lastCharacter = function(str) {
    return str.slice(-1);
};

var middleCharacters = function(str) {
    return str.slice(1, -1);
};

var isPalindrome = function(str) {
    if(str.length < 2) {
        return true;
    } else {
        if(firstCharacter(str) == lastCharacter(str)) {
            isPalindrome(middleCharacters(str));
        } else return false;
    }
};

var checkPalindrome = function(str) {
    console.log("Is this word a palindrome? " + str);
    console.log(isPalindrome(str));
};


checkPalindrome("a");
//Program.assertEqual(isPalindrome("a"), true);
checkPalindrome("matom");
//Program.assertEqual(isPalindrome("motor"), false);
checkPalindrome("rotor");
//Program.assertEqual(isPalindrome("rotor"), true);

当然,递归调用中肯定有问题。我很希望得到您的帮助。谢谢。我附上了我的代码输出结果。 enter image description here

3
你忘记了在递归调用中添加 return 语句。 - CertainPerformance
.slice 返回一个数组,然后你尝试使用 firstCharacter(str) == lastCharacter(str) 比较两个切片。你不能这样比较数组。 - Mulan
9个回答

11

这里是另一个递归回文。

function checkPalindrome(str){
    if(str.length === 1) return true;
    if(str.length === 2) return str[0] === str[1];
    if(str[0] === str.slice(-1)) return checkPalindrome(str.slice(1,-1))
    return false;
}

console.log(checkPalindrome('a')) // true
console.log(checkPalindrome('matom')) // false
console.log(checkPalindrome('rotor')) // true

6

您定义了isPalindrome()返回一个值,因此如果您自己调用它(递归或其他方式),则需要处理该返回值。另外,您的if ... else逻辑过于复杂,请简化:

var isPalindrome = function(str) {
    if (str.length < 2) {
        return true;
    }

    if (firstCharacter(str) == lastCharacter(str)) {
        return isPalindrome(middleCharacters(str));
    }

    return false;
};

5
    const isPalindrome = str => {
    const strLen = str.length;
    if (strLen < 2) return true;

    if (str[0] === str[strLen - 1]) {
        return isPalindrome( str.slice(1, strLen - 1) );
    }

    return false;
};

console.log(isPalindrome('madam'));

1
这段代码可以进行修改:如果 (strLen < 2) 返回 true; - Jason Rice

1
使用 slice 会创建一个数组 - 如果你想比较第一个和最后一个字符,你需要在应用 == 前从数组中提取该值 -
var firstCharacter = function(str) {
    return str.slice(0, 1)[0] // <-- get the first element of the slice
}

var lastCharacter = function(str) {
    return str.slice(-1)[0] // <-- get the first element of the slice
}

这是另一种递归解决方案,使用参数l(左)和r(右)通过索引检查字符串(而不是使用slice创建中间值)-

const palindrome = (s = "", l = 0, r = s.length - 1) =>
  r - l < 2
    ? true
    : s[l] === s[r] && palindrome (s, l + 1, r - 1)

console.log
  ( palindrome ("motor")   // false
  , palindrome ("rotor")   // true
  , palindrome ("racecar") // true
  , palindrome ("wow")     // true
  , palindrome ("i")       // true
  )

这里有一个相互递归的定义。虽然它是浪费的,但它仍然具有优雅的形式 -

const pal = ([ s, ...more ]) =>
  more.length === 0 || pal2 (more.reverse(), s)

const pal2 = ([ s, ...more ], q) =>
  s === q && pal (more.reverse())

console.log
  ( pal ("motor")   // false
  , pal ("rotor")   // true
  , pal ("racecar") // true
  , pal ("wow")     // true
  , pal ("i")       // true
  )


更正:String.prototype.slice 实际上返回一个字符串,所以 [0] 的添加是不必要的(虽然在这里无害)。 - Scott Sauyet

0
这里有一个简单的答案。基本上,我们正在比较第一个字符和最后一个字符,并根据情况采取行动。
const isPalindrome = str => {
  if (str.length <= 1) return true;
  if (str[0] !== str[str.length - 1]) return false;
  
  return isPalindrome(str.slice(1,-1))
}

0

2022年,我对递归回文检查的简单实现:

function isPalindrome(str) {
  if (!str.length || str.length === 1) return true;
  return str[0] === str.at(-1) ? isPalindrome(str.substr(1, str.length - 2)) : false;
}
console.log(isPalindrome('catotac'));

迭代分解:

// 1st iteration:
isPalindrome('catotac');
//2nd iteration
isPalindrome('atota');
//3rd
isPalindrome('tot');
// 4th iteration
isPalindrome('o'); // true

0
const isPalindrome = str => {
    
    // base case
    if(str.length === 1) return true;
    if(str.length === 2) return str[0] === str[1];

    if(str[0] === str[str.length - 1]) {
        return isPalindrome(str.slice(1, -1))
    }

    return false;
}

你可以使用递归

基本情况

我们需要一个基本情况(简单情况),如果字符串只有一个字符,我们简单地返回 true。

如果它有两个字符,我们检查第一个字符是否与第二个字符相同,如果相同,就返回 true。

递归情况

如果它超过了两个字符,我们检查第一个和最后一个字符是否相同,如果它们不相同,我们就简单地返回 false。

但是,如果它们相同,我们现在想要对其他字符做同样的事情,所以我们调用相同的函数,使用相同的字符串,但删除第一个和最后一个字符,因为我们已经知道它们是相同的,并继续进行,直到我们达到基本情况。

希望这对你有用。

一些测试

isPalindrome('p')    // true
isPalindrome('po')   // false
isPalindrome('pp')   // true
isPalindrome('pop')  //true

请注意,如果字符串为空,则此操作将失败。如果您使用 if (str.length < 2) return true 替换两个基本情况保护,它将被修复并简化。还要注意函数名称拼写错误。 - Scott Sauyet

0
这个解决方案怎么样?
function isPalindrome(str){
  if (str.length > 3) return isPalindrome(str.substring(1, str.length-1));
  return str[0] === str[str.length-1];
}

0

这里是另一种使用JS递归检查回文的方法:

function isPalindrome(str){ if (str[0] === str[str.length - 1] && str.length > 1) { isPalindrome(str.substring(1, str.length -1)) return true }else{ return false } }


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