2017-10-06 18 views
1

リストのリストのすべてのリストの最初の要素を削除しようとしています。 たとえば、[[1,2]、[3,4]]を表示するには、[[2]、[4]]を返す必要があります。 ほとんどの状況では、以下のこのコードは正常に動作します:Prologのリストのリストの各リストから最初の要素を削除する最も良い方法は?

remove_firstElem([],[]). 
remove_firstElem([[_H|T]|Ls],[T|L]) :- 
    remove_firstElem(Ls,L). 

しかし、私は希望[1]、[2] []のようなリストのために、それは[[]、[]]、[]を返すのではなくします。私がこれまで試したどのような

は、次のようになります。

remove_firstElem([_H|Ls],L) :- 
    length(_H,1), 
    remove_firstElem(Ls,L). 

しかし、それは[ ],[[ ]],[[ ]],[[ ],[ ]]を返し、私は本当にそれが悪いのか分かりません。

私はそれを修正する手助けはできますか?助けてくれてありがとう!

+0

pop_list([],[]). pop_list([[_,H2|T]|TA],[[H2|T]|TB]) :- pop_list(TA,TB). pop_list([[]|TA],TB) :- pop_list(TA,TB). pop_list([[_]|TA],TB) :- pop_list(TA,TB). 

を私たちは、さらにバックトラックの量が少なくなるような文を、並べ替えることができます。 'remove_firstElem([[]]、L)'と似ています。 –

+0

を[[]]に戻すと、[]が返されます。返されるリストに空のリストは存在しません。 – Fallin

答えて

1

私が正しく理解していれば、リストの先頭をポップしたいが、リストに要素が1つしかない(または全くない)場合は、そのリストを削除する必要がある。

サブリストは、パターンを有する少なくとも2つの要素が含まれている場合我々は確認することができます。

pop_lists([[_,H2|T]|TA],[[H2|T]|TB]) :- 
    pop_lists(TA,TB). 

ので、ここで私たちは、最初のリストのためのパターン[_,H2|T]を持っています。 _は、最初の要素であるH2と2番目の要素で、残りの要素はテールでバインドします。

そのパターンで統合できないリストは、空のリスト、または1つの要素を持つリストです。だから、その場合には、我々は、単にそれらを無視:場合

pop_lists([[]|TA],TB) :- 
    pop_lists(TA,TB). 
pop_lists([[_]|TA],TB) :- 
    pop_lists(TA,TB). 

を我々はリストの最後に達し、もちろん我々としても空のリストでフィルタを統一:

pop_list([],[]). 

我々はこれをよりよく置きます述語をより多方向にするために、最初の行にだから、フルで、我々は次のソリューションがあります:ソースの空のリストがある場合はどう

pop_list([],[]). 
pop_list([[]|TA],TB) :- 
    pop_list(TA,TB). 
pop_list([[_]|TA],TB) :- 
    pop_list(TA,TB). 
pop_list([[_,H2|T]|TA],[[H2|T]|TB]) :- 
    pop_list(TA,TB). 
+0

ありがとう、本当にスマートでクリアなソリューションです。しかし[[1]、[2]]のようなリストに[]とfalseを返しますが、それを避ける方法はありますか? – Fallin

+0

@ファリン:それは実際には同じです。 'false'はPrologが他の節を試す必要があるからです(別の解答を求めて)。それが失敗するので、それは偽と言う。だから基本的にそれは言う: "*答えは' [] 'であり、他の答えはない*" –

+0

@Fallin:節を並べ替えることで、おそらくそれを避けることができるだろう:) –

関連する問題