我一直在尝试编写一个谓词来评估列表的大小是否为偶数,并且必须在不计算列表长度或任何算术运算的情况下完成此操作。据说它比计算长度更容易,但我很难考虑如何做到这一点。我猜是一种递归技术,但如果有人能够提供帮助,那就太好了。
问问题
3425 次
4 回答
7
是的,你想要递归。基本情况将是您可以拥有的最小的奇数/偶数列表,然后您只需要弄清楚如何构造递归调用,以便将其归结为基本情况。您可以从想象一个长度为 3 的列表开始,该列表应该为“oddList”返回 true。如果这不是基本情况,那么下一个合乎逻辑的步骤是什么?奇数列表与偶数列表有何不同?
于 2012-05-14T09:57:36.000 回答
4
保持逻辑纯度!只需像这样进行:
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]
...
于 2015-07-27T06:49:26.773 回答
2
使用元谓词 foldl/4
和Prolog lambda,我们需要做的就是:
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]
...
于 2015-09-15T17:32:52.443 回答
1
我知道现在回答您的问题为时已晚,但希望这会有所帮助:
查找列表的长度为奇数:
oddlength([_]).
oddlength([_,_|R]) :- oddlength(R),!.
查找列表的长度是偶数:
evenlength([]).
evenlength([_,_|R]) :- evenlength(R),!.
于 2014-05-01T05:25:53.110 回答