2

sublist(L1,L2,I,J)

渡されるリストがありL1、2 つのインデックスIとがあり、との間の要素を含む包括的なサブリストJになりたいと考えています。 範囲外の場合は、リストの最後まで行ってほしいです。同様に、が 0 未満の場合は、リストの先頭から まで取得したいと考えています。 >空のリストを返します。 L2IJ
JIIJIJ

私がこれまでに持っているもの:

sublist(_,[],I,J):-
    I > J.  
sublist(Xs,Ys,I,Length):-
    length(Xs,Length),
    N > L,
    sublist(Xs,Ys,I,J).  
sublist([X|_],[X],1,1).  
sublist([X|Xs],[X|Ys],1,J):-
    J > 1,
    J1 is J - 1,
    sublist(Xs,Ys,1,J1).  
sublist([_|Xs],Ys,I,J):-
    I > 1,
    I1 is I - 1,
    J1 is J - 1,
    sublist(Xs,Ys,I1,J1).
4

2 に答える 2

4

これは、戦略を再考することで解決できます。

まず、基本ケースは何ですか?

  • 入力として空のリストになります
  • あなたが持っているI > J

どちらの場合も、空のリストをこれまでのすべてのものに追加し、それを良いと呼びます。

次に、気になるエッジケースは何ですか?

  • Jリストの終わりを超えています
  • Iリストの先頭の前です

最初のケースでは、入力リストの最後までトラバースします。2 番目では、入力リストの先頭から開始します。

さて、それを実装してみましょう。アキュムレータを使用して、呼び出しをラップします。

sublist(L1, L2, I, J):-
    sublist(L1, Temp, I, J, []),
    !,
    reverse(Temp, L2).

入力 list L1、出力 list として統合する変数、およびL2インデックス とを取ります。他のソリューションのバックトラックを心配する必要がないように使用しており、蓄積されたリストが逆に構築されているため、それを逆にします。IJcut

ベースケースに取り組みましょう。

入力として空のリスト。アキュムレータを出力リストと統合するだけです。この時点では、インデックスは気にしません。J結局のところ、これは がリストの末尾を超えているというエッジ ケースも満たしています。その時点で、すべての入力リストがアキュムレータに蓄積され、まだ J 値が残っているためです。

sublist([], L2, _I, _J, L2).

I > J で、アキュムレータを出力リストと統合します。入力リストはもう気にしません。

sublist(_L1, L2, I, J, L2):-
    I > J.

今、エッジケース。

Jリストの終わりを超えて上で解決されました。

Iリストの先頭の前にある場合は、そのインデックスを 0 に設定して先に進みます。

sublist(L1, L2, I, J, L2):-
    I < 0,
    sublist(L1, L2, 0, J, L2).

あとは実際のロジックを実装するだけです。正しいものから始めて累積したいだけですI。それでは、I目的の場所に到達するまで、入力リストの一部をデクリメントして破棄しましょう。インデックスの最後を一致させるために、デクリメントJも必要です。このようにして、インデックス間の距離を同じに保ちます。

sublist([_L|Ls], L2, I, J, Acc):-
    I > 0,
    sublist(Ls, L2, I-1, J-1, Acc).

私たちはついに私たちがなりたい場所にいます。それでは、入力リストの一部を使ってリストを作成してみましょう。これは、基本ケースの 1 つに到達するまで続きます。sublistその後、アキュムレータは元の節に戻されます。

sublist([L|Ls], L2, I, J, Acc):-
    sublist(Ls, L2, I, J-1, [L|Acc]).

すべてをまとめると、次のようになります。

sublist(L1, L2, I, J):-
    sublist(L1, Temp, I, J, []),
    !,
    reverse(Temp, L2).
sublist([], L2, _I, _J, L2).
sublist(_L1, L2, I, J, L2):-
    I > J.
sublist(L1, L2, I, J, L2):-
    I < 0,
    sublist(L1, L2, 0, J, L2).
sublist([_L|Ls], L2, I, J, Acc):-
    I > 0,
    sublist(Ls, L2, I-1, J-1, Acc).
sublist([L|Ls], L2, I, J, Acc):-
    sublist(Ls, L2, I, J-1, [L|Acc]).

そして、次のようにテストできます。

?- sublist([1,2,3,4,5], S, 0,3).
S = [1, 2, 3, 4].

?- sublist([1,2,3,4,5], S, -1,30).
S = [1, 2, 3, 4, 5].

?- sublist([1,2,3,4,5], S, 3,1).
S = [].

?- sublist([1,2,3,4,5], S, 3,3).
S = [4].

?- sublist([1,2,3,4,5], S, 3,4).
S = [4, 5].
于 2013-05-08T03:22:15.700 に答える
0

2番目の句にタイプミスがあると思います。要件を満たすために必要なこの(テストされていない)修正を試してください

J が範囲外にある場合は、I からリストの最後に移動したいと思います。

sublist(Xs,Ys,I,J):-
    length(Xs,Length),
    J > Length,
    sublist(Xs,Ys,I,Length).
于 2013-05-08T05:13:37.703 に答える