计算Haskell中2个整数之间的回文数的线性递归方法

Linear recursive method for counting palindrome numbers between 2 integers in Haskell

我正在解决 Haskell 中的一道练习题,我试图计算 2 个给定整数之间的回文数。个位数是回文。我试过用辅助函数解决它,但我不能让它从主函数中获取较小的数字。任何帮助,将不胜感激! 到目前为止,我输入了这个:

main :: IO()
main = do
print $ countPalindromes 5 13 == 5 -- 6 7 8 9 11
print $ countPalindromes 13 5 == 5 -- 6 7 8 9 11

rev :: Int -> Int
rev n = helper n 0
where
 helper :: Int -> Int -> Int
 helper 0 result = result
 helper n result = helper (div n 10) (result * 10 + mod n 10)

isPalindrome :: Int -> Bool
isPalindrome x = rev x == x

countPalindromes :: Int -> Int -> Int
countPalindromes a b
  | a > b = helper b a 0
  | otherwise = helper a b 0
  where
      helper :: Int -> Int -> Int -> Int
      helper a b count
       | a <= b && isPalindrome (a - 1) = count + 1 
       | otherwise = helper (a - 1) b count

那不是你的问题。问题是如果 a 是回文,helper a b count 只有 return 和 count + 1,而不会检查 a + 1a + 2 等是否是回文也是如此。当第一个数字是回文时,它 returns 0 + 1 == 1 就完成了。 (您对 helper 的定义也以错误的方式计数;它是 decrementing a 而不是 incrementing如果您希望 a <= b 为假,请执行此操作。)

helper需要递归是否a是否回文;唯一的区别在于其 第三个 参数的值。

helper a b count | a > b = count  -- base
                 | isPalindrome a = helper (a + 1) b (count + 1)
                 | otherwise = helper (a + 1) b count

注意 b 永远不会改变;它不需要成为 helper 的参数。相反,您可以递归调用 countPalindromes 以确保 a < b:

countPalindromes :: Int -> Int -> Int
countPalindromes a b
  | a > b = countPalindromes b a
  | otherwise = helper a 0
  where
      helper :: Int -> Int -> Int
      helper a count
        | a > b = count  -- base case
        | isPalindrom a = helper (a + 1) (count + 1)
        | otherwise = helper (a + 1) count

尾递归在 Haskell 中也不是特别重要。你可以写helper更自然

helper a | a > b = 0
         | isPalindrome a = 1 + helper (a + 1)
         | otherwise = helper (a + 1)

还请注意,isPalindrome return 与 TrueFalse 之间的唯一区别在于您添加的是 1 还是 0 到递归 return 值。您可以使用 fromEnum:

捕获它
helper a | a > b = 0
         | otherwise = (fromEnum (isPalindrome a)) + helper (a + 1)

作为练习,请注意您根本不需要显式递归。您可以使用 filter 获取回文范围内的值,然后简单地计算结果列表中值的数量。