在 Haskell 中比较两个字符串

4

我看到一个相当愚蠢的练习题,被列为简单,所以我认为我可以做到。这个前提是医生必须听到病人说“啊”才能进行诊断,但病人的“啊”必须与医生要求的“啊”相匹配。如果医生要求“啊啊啊啊”而病人只说“啊”,则无法给出诊断。Haskell程序应该按照医生和病人的“啊”的顺序读取,并返回一个bool值,表示是否可以进行诊断。起初我认为它们需要完全一致,所以我的代码是:

seeDoctor :: String -> String -> Bool
seeDoctor a b = if a == b then True
                else False

然而,我意识到自己没有遵守问题的所有规则,并不是那么简单。病人可能说“啊”比医生更长,并返回True,因此“啊”“啊啊啊”返回True,就像“”“啊啊啊”和“h”“啊”一样,但是“啊啊啊”“ah”返回False。但即使医生在他们的“啊”中不包括'h',病人也必须包括'h',因此“a”“a”返回False,但我的代码会返回True。因此,如果病人说任何话,它必须是必要数量的'a'后跟单个'h'且没有其他字符。您看,一旦我开始尝试建议的测试用例,我就意识到我了解得很少。我可以记住每个字符串中的'a'计数吗?我怎么检查额外的字符?抱歉阅读这篇文章需要一些时间。感谢您阅读到这里。
以下是确切的问题:
“当我们去看医生时,医生总是要求我们说“啊”。 有时候,医生需要我们说“啊啊啊”,但我们只能说“啊”。 在这种情况下,医生无法诊断我们的疾病,因为我们“啊”中的'a'比他或她的要求少。 现在,编写一个名为seeDoctor的Haskell函数来判断医生是否能够诊断我们的“啊”。 函数的输入由两个字符串组成。第一个字符串是医生需要的“啊啊啊”,第二个字符串是我们能够说出的“啊”。 如果我们的“啊”符合医生的要求,则输出“True”,否则输出“False”。 仅当使用小写'a'和'h',并且每个字符串包含一定数量的'a'后跟单个'h'时,测试才会通过。”

你能原封不动地发布请求吗?你描述的方式不是很清楚。 - Willem Van Onsem
2
seeDoctor "foo" "aaaaaaaah" 的输出应该是什么? - Mark Seemann
1
为什么你不只是过滤掉所有的“a”,然后比较它们的长度呢? - Redu
还要注意,你的第一次尝试是一个常见的反模式。每当你看到 if p then True else False,你可以直接写成 p。在这种情况下,你甚至可以写成 seeDoctor = (==),而不必明确指定参数。 - Thomas M. DuBuisson
问题是 https://open.kattis.com/problems/aaah - ggorlen
显示剩余2条评论
1个回答

9

既然您想学习Haskell,我不会给您一个解决方案,但我会尽力给您足够的提示,让您能够自己组合一个函数。

字符串就是列表,所以您可以使用来自Data.List的常规列表函数。例如,isSubsequenceOf几乎可以满足您的需求:

Prelude Data.List> isSubsequenceOf "aah" "aaah"
True
Prelude Data.List> isSubsequenceOf "aaaah" "aah"
False

如果我正确地理解了问题描述,您可能还应该检查输入字符串中只有ah,并且h是最后一个字符。
为了检查h是否是最后一个字符,可以使用last函数:
Prelude Data.List> last "aaaah"
'h'
Prelude Data.List> last "ah"
'h'
Prelude Data.List> last "foo"
'o'

也许您还希望检查输入是否包含异常字符,如果两个字符串中包含除 ah 以外的任何其他字符,则返回 False ...
Prelude Data.List> all (\c -> c == 'a' || c == 'h') "aaah"
True
Prelude Data.List> all (\c -> c == 'a' || c == 'h') "aaah!"
False

如果出现像"aha"这样的字符串,您会怎么处理呢?我将把这留作练习 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接