我正在写一个函数来确定一个数字是否是回文。
我想在第一种情况下做的是将字符串解构为第一个字符,中间的所有字符和最后一个字符。我所做的是检查第一个字符是否等于最后一个字符,如果是,则继续检查中间字符。
我的内容如下,但在编译时会产生类型错误。
numberIsPalindrome :: Int -> Bool
numberIsPalindrome n =
case nString of
(x:xs:y) -> (x == y) && numberIsPalindrome xs
(x:y) -> x == y
x -> True
where nString = show n
答案 0 :(得分:3)
使用String
表示是作弊......
不是,但这更有趣:
import Data.List
palindrome n = list == reverse list where
list = unfoldr f n
f 0 = Nothing
f k = Just (k `mod` 10, k `div` 10)
它的作用是创建数字的数字列表(unfoldr
对这些任务非常有用),然后比较反转时列表是否保持不变。
您尝试的有几个问题,例如你错过了从数字到String
的转换(这只是Haskell中Char
的列表),并列出了与你尝试的完全不同的工作:把它们想象成堆栈,你通常在哪里只在一端操作。
也就是说,列表有一个init
和一个last
函数,可以让你从"外部"内部列表的元素。一个天真(低效)的实现可能如下所示:
palindrome n = f (show n) where
f [] = True
f [_] = True
f (x : xs) = (x == last xs) && (f (init xs))
但这仅用于演示目的,不要在现场直播中使用此类代码......
答案 1 :(得分:1)
您可能想要的定义是
numberIsPalindrome :: Int -> Bool
numberIsPalindrome num = let str = show num
in (str == reverse str)
答案 2 :(得分:1)
(:)
运算符称为cons
,它将项目添加到列表中:
1:2:[]
会产生[1,2]
您收到类型错误,因为您尝试将第一个参数Char
与最后一个参数[a]
进行比较。
如果你真的想比较第一个和最后一个,你会使用head
和last
。
但您最好使用taktoa建议的解决方案:
numberIsPalindrome :: Int -> Bool
numberIsPalindrome num =
numberString == reverse numberString
where numberString = show num