【问题标题】:Decide if the first argument's list contains elements in the second argument's list确定第一个参数列表是否包含第二个参数列表中的元素
【发布时间】:2021-12-19 12:55:18
【问题描述】:

定义

listCheck :: [[Char]] -> [[Char]] -> Bool

决定第一个参数的单词列表是否包含也在第二个参数列表中的单词的函数。我们可以假设两个列表都只包含小写字母。如果至少有一个参数是空列表,则返回False

例如:

listCheck ["hey", "hello", "hi"] ["whatsup", "hi"] == True
listCheck ["hey", "hello", "hi"] ["whatsup"] == False

到目前为止,我已经尝试过:

listCheck [] _ = False
listCheck _ [] = False    
listCheck (x:xs) [y]
  | x == y = True
  | otherwise = listCheck (xs) [y]

这符合我的预期。它只检查第二个参数的第一个元素(如果第二个列表只有一个元素,它总是返回正确的值,所以至少我做对了)。我不知道如何为第二个列表的其余元素实现递归。

【问题讨论】:

  • 这些不是参数,而是参数。参数是变量,参数是值。

标签: haskell recursion


【解决方案1】:
listCheck :: [[Char]] -> [[Char]] -> Bool
listCheck [] _ = False
listCheck (x:xs) ys = go x ys || listCheck xs ys where
   go _ [] = False
   go x (y:ys)
     | x == y = True
     | otherwise = go x ys

我们使用辅助函数go 将一个列表中的一个元素与另一个列表中的所有元素进行比较。如果在ys 列表中找不到元素x,我们会在ys 上尝试xs 的其余部分。 || 保证一旦找到匹配项,函数就会返回,而不检查其余部分。最后,如果xs用尽了我们可以确定没有匹配并返回False

【讨论】:

  • 感谢您的详细解答!还有一个问题:在这种情况下,|| 是指 or 还是类似于 C++ 中的 break 语句?
  • || 是一个逻辑或仅当 LHS 评估为 False(如短路)时才执行 RHS。如果 LHS 计算结果为 True,则它只返回 True,而不考虑 RHS。此外,AFAIK,|| 也是短路逻辑或 C++。
  • 我明白了,谢谢你的帮助。
  • 你可以在go中使用同样的||技巧; go x (y:ys) = x == y || go x ys.您也可以使用现有的功能; listCheck xs ys = any (`elem` ys) xs。为提高效率,请使用Set,如listCheck xs ys = any (`S.member` S.fromList ys) xs
  • @DanielWagner 这就是答案。 :)
猜你喜欢
  • 1970-01-01
  • 2021-05-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多