我对Haskell来说是一个全新的(在当前版本之前只编写了一个fizzbuzz程序)并且我正在尝试编写一个带有unix wordlist的程序(' / usr / share / dict / words&# 39;)并打印出该单词的字谜列表,任何直接的回文标记。我总结了这个功能:
findAnagrams :: [String] -> [(String, [String])]
findAnagrams d =
[x | x <- map (\s -> (s, [if reverse s == t then t ++ "*" else t | t <- d, s /= t && null (t \\ s)])) d, not (null (snd x))]
然而,当我运行程序时,我得到了这个输出:
abase: babes, bases
abased: debase
abasement: basements
abasements: abatements
abases: basses
等等,很清楚它没有正常工作。我的目的是将列表理解解读如下:对于所有t in d使得t不等于s并且除了order之外t和s之间没有差别,如果t是s的反向包括t *,否则包括为t。问题似乎在于&#34; t和s之间没有区别&#34;部分,我试图通过使用&#34; null(t \ s)&#34;来完成。它似乎应该工作。在GHCI中进行测试得出:
Prelude Data.List> null ("abatements" \\ "abasements")
False
然而它通过了谓词测试。我的假设是我在这里遗漏了一些简单的东西,但是我已经看了一段时间并且无法想出它。
此外,我们将非常感谢有关最佳做法的任何注释。
答案 0 :(得分:1)
如果你把它分解成多个函数(请记住,源代码大小并不那么重要),你可以这样做:
import Data.List
isPalindrome :: String -> Bool
isPalindrome s = s == reverse s
flagPalins :: [String] -> [String]
flagPalins [] = []
flagPalins (x:xs)
| isPalindrome x = x ++ "*"
| otherwise = x
isAnagram :: String -> String -> Bool
isAnagram s t = (isPalindrome s || s /= t) && ??? -- test for anagram
findAnagrams :: String -> [String] -> [String]
findAnagrams s ws = flagPalins $ filter (isAnagram s) ws
findAllAnagrams :: [String] -> [(String, [String])]
findAllAnagrams ws = filter (not . null . snd) ??? -- words paired with their anagrams
我故意留下一些漏洞让你填写,我不打算给你所有答案;)
你自己只有两个点。 findAllAnagrams
中的那个应该很容易理解,你已经在做与map (\s -> ...)
部分非常相似的事情了。我有意组织了isAnagram
所以它会返回True
如果它是一个回文或者它只是一个字谜,你只需要再检查一次以确定t
是否是{{1}的字谜1}}。看看我在你的问题上做出的评论,以暗示在那里做什么。如果你卡住了,评论并要求额外的提示,我会给你一个我认为你应该用来解决这个问题的函数的名称。
如果你真的想要列表理解,我会建议用这种方式解决它,然后转换回理解。通常,您应该编写更详细的代码,然后在完全理解之后对其进行压缩。
答案 1 :(得分:1)
将a \\ b
视为&#34; a
中不属于b
的项目。&#34;
考虑其影响。