.net f#得到数组中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

我试图得到一个数组中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:类型不匹配。期待 “但是给了一个 '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
    不是一个好的起点。注意整数溢出可能会发生(我的函数中还没有解决)

作为使用显式递归的替代方法,您还可以使用现有的F#库函数来解决此问题。这就是大多数F#数据处理的编写方式,但是学习如何手工编写递归函数总是很好的(因为有时需要它们)

因此,为了完整起见,这里有一种使用现有函数以更声明的方式解决问题的方法:

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