我一直在尝试编写一个谓词,它会将列表的大小评估为偶数与否,这必须在不计算列表长度或任何算术运算的情况下完成。据说比计算长度更容易,但我没有想到如何做到这一点。我猜测是一种递归技术,但是如果有人能够帮助它会很棒。
答案 0 :(得分:7)
是的,你想要递归。基本情况将是您可以拥有的最小的奇数/偶数列表,然后您需要的是弄清楚如何构造递归调用,以便它可以归结为基本情况。您可以通过想象一个长度为3的列表开始,该列表应该为“oddList”返回true。如果它不是基本情况,那么下一个合乎逻辑的步骤是什么?奇数列表与偶数列表有何不同?
答案 1 :(得分:4)
保留logical-purity !只需按照以下步骤操作:
evenlength([]). % smallest list with even length is [] (length=0)
evenlength([_|Xs]) :-
oddlength(Xs).
oddlength([_|Xs]) :- % smallest list with odd length is [_] (length=1)
evenlength(Xs).
evenlength/1
和oddlength/1
的一些简单的地面查询:
?- evenlength([]).
true.
?- oddlength([]).
false.
?- evenlength([1]).
false.
?- oddlength([1]).
true.
?- evenlength([1,2]).
true.
?- oddlength([1,2]).
false.
?- evenlength([1,2,3]).
false.
?- oddlength([1,2,3]).
true.
请注意,这些谓词不仅可以测试候选列表,还可以生成它们:
?- evenlength(Xs).
Xs = []
; Xs = [_A,_B]
; Xs = [_A,_B,_C,_D]
; Xs = [_A,_B,_C,_D,_E,_F]
...
?- oddlength(Xs).
Xs = [_A]
; Xs = [_A,_B,_C]
; Xs = [_A,_B,_C,_D,_E]
; Xs = [_A,_B,_C,_D,_E,_F,_G]
...
答案 2 :(得分:2)
使用meta-predicate foldl/4
和Prolog lambdas我们需要做的就是:
evenlength(Xs) :-
foldl(\_^E^O^(O is \E),Xs,1,1). % each item in `Xs` flips the "evenness flag"
样本使用:
?- evenlength([]).
true.
?- evenlength([_]).
false.
?- evenlength([_,_]).
true.
?- evenlength([_,_,_]).
false.
?- evenlength([_,_,_,_]).
true.
让我们不要忘记最常见的查询!
?- evenlength(Xs).
Xs = []
; Xs = [_A,_B]
; Xs = [_A,_B,_C,_D]
; Xs = [_A,_B,_C,_D,_E,_F]
...
答案 3 :(得分:1)
我知道回答你的问题为时已晚,但希望这会有所帮助:
查找列表有奇长:
oddlength([_]).
oddlength([_,_|R]) :- oddlength(R),!.
查找列表的长度是均匀的:
evenlength([]).
evenlength([_,_|R]) :- evenlength(R),!.