使用 Haskell 从基本字符串构建回文

Building a palindrome from a base string using Haskell

在 Haskell 中,我想创建一个函数 formPalindrome,它接受一个字符串和 returns 可能的最短回文,输入字符串作为字符串的开头。

例如:

formPalindrome “sun” ⇒ “sunus”

formPalindrome “level” ⇒ “level”

到目前为止,我有以下内容:

formPalindrome :: String -> String
formPalindrome x
 | isPalindrome x = x
 | otherwise      = makeNewPalindrome x

对吗?

而不是立即解决最短回文扩展基本字符串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 更接近回文:从左到右或从右到左阅读,它们都以字符 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 其中 takeNxsxs 的所有初始段的列表。您知道如何生成该列表吗?

哪些候选是真正的回文?

现在您已经有了候选项列表并且知道如何检测字符串是否为回文,您可以删除所有不是回文的候选项,只保留有效的。

最小回文数在哪里?

一旦你有了 xs 的回文扩展列表,你可以简单地选择最小的一个。大功告成!