Sar*_*ner 3 algorithm haskell functional-programming
我想要的基本上是对列表的O(n ^ 2)迭代.假设我有两个整数的列表,
let list = [2312, 8000, 3456, 7000, 1234]
Run Code Online (Sandbox Code Playgroud)
以及检查是否将两个整数加在一起会产生高于20000的结果的函数(这可能是一个任意函数,它接受两个整数并返回一个布尔值).
myPredicate :: Int -> Int -> Bool
myPredicate x y = x + y > 10000
Run Code Online (Sandbox Code Playgroud)
有没有办法将此谓词应用于上面的列表,以获取包含有效对的列表列表,如下所示:
>> filter myPredicate list
>> [[2312, 8000], [3456, 8000], [3456, 7000], [8000, 7000]]
Run Code Online (Sandbox Code Playgroud)
这直接由Haskell语法支持.
[(x, y) | x <- myList, y <- myList, x + y > 20000]
Run Code Online (Sandbox Code Playgroud)
这将返回反向和重复对.如果这不是您所需要的,请考虑以下列表理解:
[(x, y) | x <- myList, y <- myList, x < y, x + y > 20000] -- no reversed pairs, no repeats
[(x, y) | x <- myList, y <- myList, x <= y, x + y > 20000] -- repeats, no reversed pairs
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因,科学不知道你有一个重复元素的列表,比如说[30000,30000] 你只想要在不同位置的元素形成有效的对,那么这个简单的列表理解将不起作用.我不知道这会是什么样的现实生活问题,但在这里你是:
[(y,z) | (y:ys) <- tails xs, z <- ys, y + z > 20000]
Run Code Online (Sandbox Code Playgroud)
(从其他答案中窃取的想法)
如果我理解你正确你想构建对列表,
pairs xs = [(y,z) | (y:ys) <- tails xs, z <- ys]
Run Code Online (Sandbox Code Playgroud)
然后使用你的谓词过滤掉它,这个谓词需要处于未经处理的形式,
myPredicate' :: (Int,Int) -> Bool
myPredicate' x y = x + y > 10000
Run Code Online (Sandbox Code Playgroud)
所以,
filter myPredicate' (pairs list)
Run Code Online (Sandbox Code Playgroud)
或者等价的
filter (uncurry myPredicate) (pairs list)
Run Code Online (Sandbox Code Playgroud)