.net f#得到数组中4个相邻数字的乘积
我试图得到一个数组中4个相邻数字的最大乘积 这就是我现在得到的:.net f#得到数组中4个相邻数字的乘积,.net,f#,.net,F#,我试图得到一个数组中4个相邻数字的最大乘积 这就是我现在得到的: let max4 line = let rec loop acc = function |a :: b :: c :: [] -> acc |a :: b :: c :: d :: tl -> loop (max(acc, a*b*c*d)) tl |_ -> 0 loop 0 line 我在max(,)上得到一个编译错误,它说: 错误FS0001
let max4 line =
let rec loop acc = function
|a :: b :: c :: [] -> acc
|a :: b :: c :: d :: tl -> loop (max(acc, a*b*c*d)) tl
|_ -> 0
loop 0 line
我在max(,)
上得到一个编译错误,它说:
错误FS0001:类型不匹配。期待
“但是给了一个
'a*'b->'a*'b当统一'a'和'a*'b->'a*'b'时,结果类型将是无限的
有人知道这个代码出了什么问题吗?(或其他解决方案)假设输入是一个整数列表:
let max4 line =
let rec loop acc = function
| x1::(x2::x3::x4::_ as xs) -> loop (max acc (x1*x2*x3*x4)) xs
|_ -> acc
loop System.Int32.MinValue line
你犯了一些错误:
- 内置的
函数是咖喱形式的max
max:'a->'a->'a
- 函数中要处理的下一个案例应该是
,而不仅仅是b::c::d::tl
tl
- 产品可能是阴性的,因此
不是一个好的起点。注意整数溢出可能会发生(我的函数中还没有解决)0
let max4 line =
line |> Seq.windowed 4
|> Seq.map (Seq.reduce (*))
|> Seq.max
第一行将列表转换为一系列4元素数组(窗口)。然后将其传递给
Seq.map
,该映射将窗口转换为元素的乘积。为此,我使用了Seq.reduce
,它使用指定的函数(这里是(*)
操作符)来减少序列(在本例中是窗口)。最后,要找到产品的最大元素,您可以使用Seq.max
函数。其他两个答案都是滑动窗口的总和,但在您的问题中,它们是连续的。如果需要后者,可以定义这样一个函数:
let groupsOf n items =
if n <= 0 then invalidArg "n" "must be greater than zero"
if List.isEmpty items then invalidArg "items" "empty list"
let rec loop i acc items =
seq {
match i, items with
| 0, [] -> yield List.rev acc
| _, [] -> ()
| 0, _ ->
yield List.rev acc
yield! loop n [] items
| _, x::xs -> yield! loop (i - 1) (x::acc) xs
}
loop n [] items
groupsOf
忽略末尾的任何部分组(代码也是如此)。数组或列表?你的问题是数组,但你的代码使用的是列表…明白了,问题是我使用的是(a,b)
而不是a b
也错过了b::c::d结尾Seq.windowed
返回滑动窗口;他问题中的代码使用连续的组。@Daniel:选定的答案也使用滑动窗口,所以我想这才是OP真正想要的。@ildjarn:也许……也许他没有注意到。嗯,跳过除第四个元素之外的所有元素都可以使用Seq.mapi
和Seq.filter
来完成。我真的不知道contigous和slide是什么,所以我将展示我在做什么,这个:,所以这个函数是上一个问题11的一部分或解决方案euler@ChuckNorris:给定的[1;2;3;4;5;6;7;8]
,您希望遵循什么[1;2;3;4]
:[2;3;4;5]
或[5;6;7;8]
?其他答案是前者,这个(和你的问题)是后者。列表中所有可能的4个相邻数字:123423456。。。5678@ChuckNorris:那就是滑动了。;-]
let max4 line =
line |> groupsOf 4
|> Seq.map (Seq.reduce (*))
|> Seq.max