在Haskell中,我想创建一个函数formPalindrome,它接受一个字符串并返回可能的最短回文,输入字符串作为字符串的开头。
例如:
formPalindrome “sun” ⇒ “sunus”
formPalindrome “level” ⇒ “level”
到目前为止,我有以下内容:
formPalindrome :: String -> String
formPalindrome x
| isPalindrome x = x
| otherwise = makeNewPalindrome x
是不是?
答案 0 :(得分:1)
而不是立即解决使最短回文延伸基础字符串xs
的问题(或者,如果我们将其视为字符列表x_0, ..., x_n
),您可能希望通过一小步进行:
回文是一个我们可以从左到右,从右到左阅读的字符串,没有任何区别。我们可以使用reverse
:
isPalindrome :: String -> Bool
isPalindrome xs = xs == reverse xs
我们正在寻找x_0, ..., x_n
的扩展,看起来有点像回文。我们可以肯定地说:
如果xs
本身不是一个回文,那么x_0, ..., x_n, x_0
离一个更近一步:从左到右或从右到左阅读它们,它们都以字符{{1}开头}}
如果x_0
不是回文,那么x_0, ..., x_n, x_0
更接近于:从左到右或从右到左阅读,它们都以x_0, x_1, ..., x_n, x_1, x_0
开头x_0
。
等。对于x_1
以及所有看起来像x_0, ..., x_n, x_2, x_1, x_0
我们知道x_0, ..., x_n, x_k, x_(k-1), ..., x_0
保证是回文,所以我们只对生成小于此的候选人名单感兴趣:
xs ++ reverse xs
可以写成:[ xs
, xs ++ reverse (take 1 xs)
, xs ++ reverse (take 2 xs)
, xs ++ reverse (take 3 xs)
, (...)
, xs ++ reverse xs ]
其中map (\ ys -> xs ++ reverse ys) takeNxs
是takeNxs
的所有初始细分的列表。你知道怎么生成那个列表吗?
既然你有候选人名单并且知道如何检测字符串是否是回文,你可以删除所有不是回文的候选人,只保留有效候选人。
一旦您获得了xs
作为回文的扩展名列表,您就可以选择最小的扩展名。而且你已经完成了!