如何计算一个元素大于其后继元素的次数?
How can I count the number of times an element is greater than its successor?
我目前正在尝试解决以下练习:
给定一个 Int
的列表,计算一个元素大于它后面的元素的次数。这个练习迫使我不要使用显式递归。
以下是给定 function :: [Int] -> Int
:
的一些示例输出
function [1, 2, 3, 4, 5] == 0 -- only increasing numbers
function [5, 4, 3, 2, 1] == 4 -- only decreasing numbers
function [2, 1, 3, 1, 0, 4] == 3
-- 2 > 1
-- 3 > 1
-- 1 > 0
function [1] == 0 -- no successor
function [ ] == 0 -- no numbers at all
我想以某种方式使用foldl
,但经过多次尝试但没有奏效,我不得不放弃。
如何在不使用递归的情况下计算一个元素大于其后继元素的次数?
首先我们需要将连续的元素配对,
foo :: [Int] -> Int
foo xs = result
where
pairs = zip xs (drop 1 xs)
然后我们可以处理每一对
biggers = [ () | (x,y) <- pairs, x > y]
现在我们可以数一数了,
result = .......
所有嵌套名称属于相同的、共享的、嵌套的范围。 result
必须利用biggers
的值,而biggers
指的是pairs
的值,指的是foo
的参数值,xs
。确保将这些代码行放入相同的定义中,全部缩进与第一行相同的缩进量,pairs
,一个在另一个下面。
其实用左折也是可以的:
foo (h:t) = snd ( foldl' (\ (a, !c) x -> (x, if (a > x) then (c+1) else c))
(h,0) t )
foo [] = 0
我想你会同意,尽管这比第一个定义更不明显。另请注意,它使用“bang pattern”,!
,连同 foldl'
,而不是 foldl
,以便在我们沿着输入列表进行计数时尽快进行计数,而不是延迟它直到所有输入列表都被完整遍历,因为 foldl
会不必要地损害整体效率。
我目前正在尝试解决以下练习:
给定一个 Int
的列表,计算一个元素大于它后面的元素的次数。这个练习迫使我不要使用显式递归。
以下是给定 function :: [Int] -> Int
:
function [1, 2, 3, 4, 5] == 0 -- only increasing numbers
function [5, 4, 3, 2, 1] == 4 -- only decreasing numbers
function [2, 1, 3, 1, 0, 4] == 3
-- 2 > 1
-- 3 > 1
-- 1 > 0
function [1] == 0 -- no successor
function [ ] == 0 -- no numbers at all
我想以某种方式使用foldl
,但经过多次尝试但没有奏效,我不得不放弃。
如何在不使用递归的情况下计算一个元素大于其后继元素的次数?
首先我们需要将连续的元素配对,
foo :: [Int] -> Int
foo xs = result
where
pairs = zip xs (drop 1 xs)
然后我们可以处理每一对
biggers = [ () | (x,y) <- pairs, x > y]
现在我们可以数一数了,
result = .......
所有嵌套名称属于相同的、共享的、嵌套的范围。 result
必须利用biggers
的值,而biggers
指的是pairs
的值,指的是foo
的参数值,xs
。确保将这些代码行放入相同的定义中,全部缩进与第一行相同的缩进量,pairs
,一个在另一个下面。
其实用左折也是可以的:
foo (h:t) = snd ( foldl' (\ (a, !c) x -> (x, if (a > x) then (c+1) else c))
(h,0) t )
foo [] = 0
我想你会同意,尽管这比第一个定义更不明显。另请注意,它使用“bang pattern”,!
,连同 foldl'
,而不是 foldl
,以便在我们沿着输入列表进行计数时尽快进行计数,而不是延迟它直到所有输入列表都被完整遍历,因为 foldl
会不必要地损害整体效率。