2012-02-15 6 views
3

2つのリストを反復処理する必要があります。 1つは空のサブリストのリストとして開始し、2番目のサブリストは最初のリストにある各サブリストの最大長を持ちます。OCamlコードは2つのリストで動作します。これを行う良い方法はありますか?

Example; list1 = [[];[];[];]; list2 = [1;2;3] 

リスト1の空のサブリストに、サブリストの長さがlist2の対応する整数を決して超えないようにする必要があります。その目的のために、私はelement、elem、および2つのリストlistとlistを与え、サブリストを記入するという次の関数を書いた。

let mapfn elem list1 list2= 
    let d = ref 1 in 
     List.map2 (fun a b -> if ((List.length a) < b) && (!d=1) 
          then (incr d ; List.append a [elem]) 
           else a) 
         list1 list2 

;;

私は今、リストの要素にこの関数を繰り返し呼び出すと、私は予想通り

この機能が働く必要がある最終的な答えを得ることができます。しかし、私はint refを使用する必要性に悩まされていません。 これを行うにはより良い方法がありますか?

+0

私は本当にあなたの説明を理解していません。あなたの現在のコード 'mapfn 42 [[]; []; [];] [3; 4; 5]'は[[42]; []; []] 'それはあなたが欲しいものですか? – newacct

+0

あなたは機能があまり意味のある結果を与えていません。私はmapfn 1 [[]] []; [];] [1; 2; 3] 'が[[1]; [1; 1; 1]]を返すのではなく、ほぼすべての空のリスト – pad

+0

@ newacct。それは実際に私が欲しいものです。リスト[[]; []; []]がプレースホルダであり、最初のサブリストに3つ以上の要素を含めることはできません。2番目のサブリストは4つ以上の要素を持つことはできず、最後の要素は5つ以上の要素を指定できません。 2番目のリスト[3; 4; 5] – ppaul74

答えて

4

私はいつもそれを見つけます解決策を形成するために一緒に構成することができるバイトサイズの断片に問題を分割する価値があります。指定した長さにリストをパディングまたは切り捨てたいとします。これは切り捨て次いで、二段階、第1のパッドに行うのは簡単である:takeは最大で所定の長さのプレフィックスサブリストを抽出しながら

let all x = let rec xs = x :: xs in xs 

let rec take n = function 
| []   -> [] 
| _ when n = 0 -> [] 
| x :: xs  -> x :: take (pred n) xs 

allは、値を繰り返すことによって、無限リストを作成します。これら2では、パディングと切り捨ては非常にstraightforwadです:

let pad_trim e n l = take n (l @ all e) 

(これが実際のOCamlのような厳格な言語で動作することを少し意外かもしれません)。その定義と、あなたの必要な機能は、単純である:

、指定された長さのリストのような第2のリストを取っている
let mapfn elem list1 list2 = List.map2 (pad_trim elem) list2 list1 

、パッド供給パディング要素とその長さに最初のリストにリストの各。例えば、mapfn 42 [[];[];[]] [1;2;3][[42]; [42; 42]; [42; 42; 42]]となります。これが必要でない場合は、要件に合わせて部品とアセンブリを微調整することができます。

3

あなたはそのようなものをお探しですか?

let fill_list elem lengths = 
    let rec fill acc = function 
    | 0 -> acc 
    | n -> fill (elem :: acc) (n - 1) in 
    let accumulators = List.map (fun _ -> []) lengths in 
    List.map2 fill accumulators lengths 

(* toplevel test *) 
# let test = fill_list 42 [1; 3];; 
val test : int list list = [[42]; [42; 42; 42]] 

(私はあなたの質問で空のリストの最初のリストの意味を作ることができなかったが、私はそれが尾-REC fill機能のためのアキュムレータかもしれ疑う。)

関連する問題