私のflattenの実装を見てください:一般的に、それは動作しています。 my_flatten([], F)
の問題のみ - F=[]
ではなくF=[]; F=[[]]
となります。 my_flatten(X, [1,2,3])
についてはプロローグで平坦化 - 他のようなもの
my_flatten(L, X) :-
my_flatten(L, X, []). %, reverse(F, X).
my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :-
my_flatten(H, F1, Acc),
my_flatten(T, F, F1), !.
my_flatten(X, [X|Acc], Acc).
このプログラムはループ - として、無限に多くの答えが存在するので、それは、OKです:[[],[],[],[],1,2,3]
。
しかし、上記と同じ問題 - my_flatten(X, [])
の場合もループするはずですが、[]; [[]]
となります。
リバーサルですが、気にしません。reverse
のコメントを外すと問題ありませんが、上記のループの代わりにfalse
が返されます。
my_flatten([], X)
の場合、[]
を返すようにこのコードを変更することはできますか?
私は@lurkerの提案を実装:
my_flatten(L, F) :-
my_flatten(L, X, []),
reverse(F, X).
my_flatten([], Acc, Acc).
my_flatten([H|T], F, Acc) :-
is_list(H),
my_flatten(H, F1, Acc),
my_flatten(T, F, F1).
my_flatten([X|T], F, Acc) :-
not(is_list(X)),
my_flatten(T, F, [X|Acc]).
カット演算子( '!')に親和性があるようです。 ;)最初の引数を時々リストにすると、時には面白いコードの匂いが出ないことがあります。 'my_flatten(X、[X | Acc]、Acc)'は、これらの2つの場所に現れるAccで問題があります。 'my_flatten/3'とは、論理的に不明であることを意味します。 'is_list(H)'は 'H 'がリストの場合は真であるので、それが便利であればそれを使うことができます。 – lurker
私はカットオペレーターの兄弟ですが、あなたはカットオペレーターのための敵です:Dヒントをお願いします。私は最初の新しい記事を投稿しました。あなたはそれについてどう思いますか ? –
カットには場所がありますが、問題を「修正」しようとすると使いにくいです。多くの初心者は、さまざまな目的のためにそれを使用しますが、しばしば途中で問題を修正しますが、それらの述語の適切な一般性を破壊してしまいます。私はカットの友人でもありますが、それが適切に意図されている場合のみです。 :) – lurker