2

我一直在尝试编写一个谓词来评估列表的大小是否为偶数,并且必须在不计算列表长度或任何算术运算的情况下完成此操作。据说它比计算长度更容易,但我很难考虑如何做到这一点。我猜是一种递归技术,但如果有人能够提供帮助,那就太好了。

4

4 回答 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/4Prolog 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 回答