3

右に「回転」した回数rotate n lと同じ要素を含む新しいリストを返す関数を書きたいと思います。例えば、ln

rotate 0 [1;2;3;4]返す[1;2;3;4]
rotate 1 [1;2;3;4]べき 返す[4;1;2;3]
rotate 2 [1;2;3;4]べき 返すべき 返すべき 返すべき 返す[3;4;1;2]
rotate 3 [1;2;3;4]べき 返す[2;3;4;1]
rotate 4 [1;2;3;4]べき[1;2;3;4]
など

rotate nfor less than 0の振る舞いはnfor equal to 0 と同じはずです。これを のリスト連結演算子をn使わずに書きたいと思います。@Pervasives

更新:これが私が書いた回転関数です:

let rot1 l =
  let rec iterate acc = function
      [] -> []
    | [x] -> x :: List.rev acc
    | x :: l -> iterate (x :: acc) l
  in
  iterate [] l;;

しかし、私はそれを使わずに同じことをしたいList.rev. これを行う方法はありますか?

4

2 に答える 2

3

ジェフリーに同意します。あなたが試したことを見せてください。始める必要がある場合に備えて、ここに小さなヒントがあります。1回転のみを実行する関数、つまり と同等の関数を作成できる場合rotate 1 l。(私はそれを呼びますone_rot)。次にrotate、次のように簡単に定義できます。

let rec rotate n l = 
  match n with 
  | 0 -> l
  | _ -> rotate (n-1) (one_rot l)

あなたの解決策は私にとって完全に問題ありません。List.rev に対して何を持っているかわかりませんが、ここでは完全にスタンドアロンone_rotです。末尾再帰を犠牲にしなければならないことに注意してください。おそらくこれもかなり短くすることができます:

let rec last = function
  | [] -> assert false 
  | [x] -> x
  | x::xs -> last xs

let rec init = function
  | [] -> []
  | [x] -> []
  | x::xs -> x::(init xs)

let one_rot l = (last l)::(init l)
于 2013-03-26T01:25:47.850 に答える