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

これには、やりたいこととより意味的に一致するという利点があります。

編集: @Daniel と @JonHarropmap2の代わりに使用しzip、感謝します。map

于 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

まず、リストを頭と尾に分割する場合は、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代わりにを使用しました。List.map2

于 2012-05-08T10:15:47.423 に答える