使用 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
其中 takeNxs
是 xs
的所有初始段的列表。您知道如何生成该列表吗?
哪些候选是真正的回文?
现在您已经有了候选项列表并且知道如何检测字符串是否为回文,您可以删除所有不是回文的候选项,只保留有效的。
最小回文数在哪里?
一旦你有了 xs
的回文扩展列表,你可以简单地选择最小的一个。大功告成!
在 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
其中 takeNxs
是 xs
的所有初始段的列表。您知道如何生成该列表吗?
哪些候选是真正的回文?
现在您已经有了候选项列表并且知道如何检测字符串是否为回文,您可以删除所有不是回文的候选项,只保留有效的。
最小回文数在哪里?
一旦你有了 xs
的回文扩展列表,你可以简单地选择最小的一个。大功告成!