0

((6, 3, 2), ( 4, 5 ,1)) などのトリプルのペアをインターリーブし、このインターリーブから 6 タプルを作成する関数を作成しようとしています。私はいくつかの調査を行いましたが、インターリーブがどのように機能するかを理解できたので、自分で何かを試してみましたが、6タプルを作成しているが正しいインターリーブ方法ではありませんでした。これは私のコードです

let interleave ((a, b, c), (a', b', c')) =
let sort2 (a, b) = if a > b then (a, b) else (b, a) in
let sort3 (a, b, c) = 
let (a, b) = sort2 (a, b) in
let (b, c) = sort2 (b, c) in
let (a, b) = sort2 (a, b) in
(a, b, c) in
let touch ((x), (y)) = 
let (x) = sort3 (x) in
let (y) = sort3 (y) in
((x),(y)) in
let ((a, b, c), (a', b', c')) = touch ((a, b, c), (a', b', c')) in
(a, b', a', b, c, c');;

どの関数を使用して適切な形式のインターリーブを実現できるかを誰かに説明してもらえますか。なぜこのようにしようとしているのかと聞かれた場合に備えて、再帰とリストについては学んでいません。ありがとうございます。

4

2 に答える 2

2

問題文では、「max」という言葉を定義せずに使用しています。OCamlの組み込みcompare関数を定義として使用すると、辞書式順序が使用されます。したがって、(6 つの値の) 最大値を 6 タプルの最初の位置に配置し、2 番目に大きい値を次に配置する、というようにします。

これは、タプルの並べ替えに関する以前に確立されたスキルを考えると、非常に簡単なはずです。

価値があることについては、2 つの 3 タプルの ID を保持することにはあまり価値がないようです。最も外側の関数に入ると、6 つの値を 6 タプルとして扱うことができます。または私にはそう思われるでしょう。

アップデート

あなたの例から(おそらく最初にそれを与えたはずです:-)、あなたが何をするように求められているかは明らかです。元のタプルの要素が元の順序になっているシーケンスになりたいが、任意にインターリーブすることができます。これはしばしば「シャッフル」(またはマージ) と呼ばれます。辞書式に最大値を持つシャッフルを見つける必要があります。

これを推論すると、2 つのタプルの先頭から最大の値を取得し、出力の次に置くことになります。

これは、リストを使用する方がはるかに簡単です。

于 2016-10-15T01:08:49.833 に答える
2

これで、あなたの最終目標が何であるかがわかりました。. .

n要素のタプルはnごとに異なる型であるため、さまざまなサイズのタプルを操作するためのヘルパー関数を定義する必要があります。

基本的にリストに対する再帰関数を模倣する 1 つのアプローチ (ただし、タプルはすべて異なる型を持つため、多くの追加関数が必要です) は、2 組のヘルパー関数を使用することです。

  • 既存のタプルの先頭に値を追加する関数:prepend_to_2から までprepend_to_5。例えば、

    let prepend_to_3 (a, (b, c, d)) = (a, b, c, d)
    
  • 可能なサイズごとに最大 3 の 2 つのタプルをインターリーブする関数: interleave_1_1interleave_1_2interleave_1_3interleave_2_2interleave_2_3およびinterleave_3_3. interleave_2_1(引数を逆の順序で呼び出すことができるので、eg は必要ないことに注意してくださいinterleave_1_2。) たとえば、

    let interleave_2_2 ((a, b), (a', b')) =
        if a > a'
        then prepend_to_3 (a, interleave_1_2 (b, (a', b')))
        else prepend_to_3 (a', interleave_1_2 (b', (a, b)))
    

    (それがどのように機能するか分かりますか?)

それからinterleaveちょうどinterleave_3_3です。

リストと再帰を使用すると、単一の関数で任意の長さのリストを操作できるため、これははるかに簡単になります。そのため、同じロジックの複数の異なるコピーは必要ありません。

于 2016-10-15T02:11:44.740 に答える