繁体   English   中英

Haskell:在列表中查找两个相关元素

[英]Haskell: Find two related elements in a list

我是 Haskell/FP 的新手。 我想解决这个任务:

给出了这个列表:[1721, 979, 366, 299, 675, 1456]

找出总和为2020的两个元素并将它们相乘。 解是 1721 * 299。

我认为在 Haskell 中,我可以用来解决这个问题的工具是列表理解和折叠(或它们的组合)。 但是我不明白如何编写一个考虑到同一列表的其他元素的列表理解,而不仅仅是当时的一个元素。

这是我几个小时后想出的( ints是列表):

print [(x,y, x*y) | x <- ints, y <- ints, x+y == 2020]

它实际上打印了正确的答案。 但我认为我的解决方案很脏:

  • 我将输入列表两次输入到列表理解中。 这个对吗? 对我来说,这似乎是开销/重复。 我确信有更好的方法。
  • function 的返回是一个包含两个相同实体的列表(我认为这是因为我在最后一个项目符号中描述的内容): [(1721,608,514579),(1721,608,514579)] - 当然我可以得到一个带有head的元素,但这并不能解决问题的根源。

这将两次发出相同值的原因是因为您在列表上有两个迭代器。 因此,这意味着在某个点x将取值为 1721 而y将取值为 299; 但稍后在程序中会出现相反的情况: x将取 299; y将取 1721。

我们可以通过使用tails:: [a] -> [[a]]轻松解决这个问题:

import Data.List(tails)

[(x,y, x*y) | (x:ys) <- tails ints, y <- ys, x+y == 2020]

这里对于ints的每个后缀,我们将x作为第一个元素, ys作为其余元素,然后我们枚举ys

但这仍然需要二次时间。 这可以通过对列表进行排序在O(n log n)上完成,然后使用递归,我们在列表的两端进行枚举,直到找到等于 2020 的值。另一种选择是使用像HashSet这样的集合. 然后我们首先将元素存储在HashSet中,然后对于列表中的每个元素x ,我们检查2020 - x是否在HashSet中。 我把这些留作执行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM