[英]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]
它实际上打印了正确的答案。 但我认为我的解决方案很脏:
[(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.