私のマージソートのための全体的なコードとの一致を実装しようとすると、このようなものに見えた:このコードは完全によく働いたF#はマージソートIndexOutOfRangeExceptionを構造
let remove array =
Array.sub array 1 (array.Length - 1)
let rec merge (chunkA : int[]) (chunkB : int[]) =
if chunkA.Length = 0 && chunkB.Length = 0 then [||]
else if chunkA.Length = 0 || chunkB.[0] < chunkA.[0] then Array.append [| chunkB.[0] |] (merge chunkA (remove chunkB))
else Array.append [| chunkA.[0] |] (merge (remove chunkA) chunkB)
let rec mergesort (array : int[]) =
let middle = array.Length/2
let chunkA = match middle with
| 1 -> [| array.[0] |]
| _ -> mergesort [| for i in 0 .. middle - 1 -> array.[i]|]
let chunkB = match array.Length - middle with
| 1 -> [| array.[array.Length - 1] |]
| _ -> mergesort [| for i in middle .. array.Length - 1 -> array.[i]|]
merge chunkA chunkB
を、私は一連のを変更したいですif merge
の文はmatch with
文に機能します。
私は、次のコードを実行しようとした:私は私のコードを実行したとき
let rec merge (chunkA : int[]) (chunkB : int[]) =
match chunkA.Length with
| 0 when chunkA.Length = chunkB.Length -> [||]
| 0 | _ when chunkB.[0] < chunkA.[0] -> Array.append [| chunkB.[0] |] (merge chunkA (remove chunkB))
| _ -> Array.append [| chunkA.[0] |] (merge (remove chunkA) chunkB)
は、Visual Studioは、特にここでは、私に "IndexOutOfRangeException" を投げた:このインスタンスで
| 0 when chunkA.Length = chunkB.Length -> [||]
、chunkA
を空であったが、chunkB
には1つの数字が入っていた。このように、F#がなぜチャンクAとBの長さが同じではないので、このケースを返そうとしたのか、私は完全にはわかりませんが、なぜ空の配列にインデックスエラーがスローされるのか混乱しています。
さらに、私はF#と関数型プログラミング一般にかなり新しいです。私のコード内の構造や方法論が同程度でない場合は、この点についてもお気軽にコメントしてください。
また、厚くなっている場合は、私にもそのことを教えてください。
多くのおかげで、 ルーク
デバッガが何らかの理由で間違った行を表示しました。実際のエラーの原因は 'chunkB。[0]
また、 '| 0 | _ chunkB。[0] '行は**両方の場合に' when'条件を適用します。 「いつ」の仕事のしくみは、新しいF#プログラマーを驚かせることが多い(それは[私を驚かせる]でも)(http://stackoverflow.com/questions/43455264/incomplete-pattern-match-when-two-patterns-share-a -when-clause)先週、私はしばらくF#を使っていました)。だから、ここの '0'の場合は' chunkB。[0]
rmunn