0

基本上,我需要编写一个谓词 , even_elts(L,M),这L是一个生成的新列表,其中仅包含来自M(0th, 2nd, 4th 等)的偶数索引元素

add_tail([X],[],X).
add_tail([H|NewT],[H|T],X) :-
   add_tail(NewT,T,X).

even_elts(L,[]) :- L = [].
even_elts(L,M) :- even_elts2(L,M,1).
even_elts2(L,[H2|T2],Ct) :-
   Ct2 is Ct + 1,
   ((Ct2 mod 2) =:= 0, add_tail(L,L2,H2), even_elts2(L2,T2,Ct2); even_elts2(L,T2,Ct2)).
even_elts2(_,[],_) :- !.

如果M为空或包含 1 或 2 个元素,则此方法有效。但是,它只从 中获取第一个偶数索引元素M,而不是其余的。任何指针

编辑:通过删除奇数索引元素而不是尝试创建新列表并复制数据来以不同的方式解决问题。但是,如果有人能为我的原始代码找出解决方案,我会很感兴趣。

4

3 回答 3

3

你让这比现在复杂得多。您可以使用模式匹配来获取每个偶数元素,然后在第二个(输出)参数中收集这些元素。

% an empty list does not have even elements
even_elts([], []).
% for all other lists, skip the second element (_),
% add the first to the output, recurse
even_elts([X, _ | L], [X | R]) :-
    even_elts(L, R).
于 2013-05-07T18:49:17.560 回答
2

使用累加器的另一种方法:

even_elts(L,M) :-
  even_elts(M,0,[],L).

even_elts([H|T],I,Acc,Ans) :-
  ( I mod 2 =:= 0, append(Acc,[H], AccNew)
  ; I mod 2 =:= 1, AccNew = Acc
  ),
  Inew is I + 1,
  even_elts(T,Inew,AccNew,Ans).

even_elts([],_,Acc,Acc).

?- even_elts(X,[1,2,3,4,5]).
X = [1, 3, 5] ;
于 2013-05-07T19:10:38.817 回答
0
evens([A,B|C], [A|D]):- !, .....
evens(X, X).

是你所需要的全部。填空。:)

于 2013-05-07T18:45:25.587 回答