次のような整数のリストを使用します。
[1;2;3;4;5;6;7;8;9]
上記のintのリストのリストを作成するにはどうすればよいですか?すべての新しいリストは同じ指定された長さです。
たとえば、次の場所から移動する必要があります。
[1;2;3;4;5;6;7;8;9] to [[1;2;3];[4;5;6];[7;8;9]]
分割する数は3ですか?
御時間ありがとうございます。
次のような整数のリストを使用します。
[1;2;3;4;5;6;7;8;9]
上記のintのリストのリストを作成するにはどうすればよいですか?すべての新しいリストは同じ指定された長さです。
たとえば、次の場所から移動する必要があります。
[1;2;3;4;5;6;7;8;9] to [[1;2;3];[4;5;6];[7;8;9]]
分割する数は3ですか?
御時間ありがとうございます。
したがって、実際に必要なのは型の関数です
val split : int list -> int -> int list list
整数のリストとサブリストサイズを取ります。さらに一般的なものはどうですか?
val split : 'a list -> int -> 'a list list
実装は次のとおりです。
let split xs size =
let (_, r, rs) =
(* fold over the list, keeping track of how many elements are still
missing in the current list (csize), the current list (ys) and
the result list (zss) *)
List.fold_left (fun (csize, ys, zss) elt ->
(* if target size is 0, add the current list to the target list and
start a new empty current list of target-size size *)
if csize = 0 then (size - 1, [elt], zss @ [ys])
(* otherwise decrement the target size and append the current element
elt to the current list ys *)
else (csize - 1, ys @ [elt], zss))
(* start the accumulator with target-size=size, an empty current list and
an empty target-list *)
(size, [], []) xs
in
(* add the "left-overs" to the back of the target-list *)
rs @ [r]
これで加点できたら教えてください!;)
私はおそらくこのようにします:
let split lst n =
let rec parti n acc xs =
match xs with
| [] -> (List.rev acc, [])
| _::_ when n = 0 -> (List.rev acc, xs)
| x::xs -> parti (pred n) (x::acc) xs
in let rec concat acc = function
| [] -> List.rev acc
| xs -> let (part, rest) = parti n [] xs in concat (part::acc) rest
in concat [] lst
が均等にn
分割されない場合は寛大であることに注意してください。List.length lst
例:
split [1;2;3;4;5] 2
与える[[1;2];[3;4];[5]]
最後の注意: OCaml の標準ライブラリは非常に骨の折れるものであるため、コードは非常に冗長です:/ 別のライブラリを使用すると、これをより簡潔にすることができると確信しています。
あなたが与えるコードは、リストの先頭から指定された数の要素を削除する方法です。進める方法の 1 つは、この関数をそのままにして (おそらく少しクリーンアップして)、外部関数を使用してリスト全体を処理することです。これを簡単に行うために、関数はリストの残りの部分も返す必要があるかもしれません (そのため、外側の関数はまだセグメント化する必要があるものを簡単に判断できます)。
ただし、単一の関数で問題を解決したいようです。もしそうなら、欠けている主なものは、すでに切り取った部分のアキュムレータです。また、カウントに達したときに終了することはできません。切り取ったばかりの部分を覚えてから、リストの残りを同じ方法で処理する必要があります。
これを自分で解決する場合は、問題を一般化して、再帰呼び出しがすべての場合に役立つようにします。うまくいくかもしれないことは、最初の部分を残りよりも短くすることです. そうすれば、アキュムレータなし (再帰呼び出しのみ) の単一の関数として記述できます。
let rec split n xs =
let rec take k xs ys = match k, xs with
| 0, _ -> List.rev ys :: split n xs
| _, [] -> if ys = [] then [] else [ys]
| _, x::xs' -> take (k - 1) xs' (x::ys)
in take n xs []