0

我正在努力实现这一目标:

7 2 3 5
10 12 20

res = 10 + max(7,2) ; 12 + max(2,3); 20 + max(3,5)

到目前为止,这是我的代码:

//prevline.count is always currLine.count+1

let getResLine currLine prevLine =
   let rec loop resLine prevLine' = function
       |[] -> resLine
       |hd::tl -> loop (hd + (max (List.nth prevLine' 0) (List.nth prevLine' 1)))::resLine (List.tail prevLine') tl
   loop [] prevLine currLine

但它不能编译,它告诉我一些类型不匹配的错误,可能更有经验的人可以看到我犯的一些明显的错误,请帮助

编辑:根据建议更新了我的代码,但它仍然无法正常工作

4

4 回答 4

9

顺便说一句,您可能对另一种看待问题的方式感兴趣。从数字列表开始:

let nums1 = [7; 2; 3; 5]
let nums2 = [10; 12; 20]

然后

let res = nums1 
          |> Seq.pairwise 
          |> Seq.map2 (fun a (b1, b2) -> a + max b1 b2) nums2

这样做的好处是在语义上与您想要做的事情更加匹配。

编辑:使用map2而不是简化zipmap感谢@Daniel 和@JonHarrop。

于 2012-05-08T10:23:04.780 回答
4

我不知道你的问题是什么,但衙役的回答可以简化为:

let res =
  Seq.pairwise nums1
  |> Seq.map2 (fun a (b1, b2) -> a + max b1 b2) nums2
于 2012-05-08T14:35:05.550 回答
2

我想这就是你想要的

let getResLine currLine prevLine =
    let rec loop resLine prevLine = function
        |[] -> resLine
        |hd::tl -> loop (hd + max (List.nth prevLine 0) (List.nth prevLine 1)) (List.tail prevLine) tl
    loop 0 prevLine currLine
于 2012-05-08T10:07:24.633 回答
2

首先,如果要将列表拆分为头部和尾部,请使用 just hd::tl(不带括号)。

其次,您似乎并没有真正创建结果列表。而且我认为您在这里不需要蓄能器。

第三,我认为在两个函数中使用相同的变量名会令人困惑(因为您可以在内部函数中使用来自外部函数的变量)。

正因为如此,我会像这样重写你的函数:

let getResLine prevLine resLine =
    let rec loop prevLine' = function
        |[] -> []
        |hd::tl -> (hd + (max (List.nth prevLine' 0) (List.nth prevLine' 1)))::loop (List.tail prevLine') tl
    loop prevLine resLine

尽管我认为使用高阶函数而不是显式递归会更具可读性:

let getResLine prevLine resLine =
    let maxes line = Seq.map2 (max) prevLine (List.tail prevLine)
    Seq.map2 (+) (maxes prevLine) resLine | Seq.toList

我使用Seq.map2, insted of List.map2,因为后者不处理长度不等的列表。

于 2012-05-08T10:15:47.423 回答