Prolog:获取一个包含两个子列表的列表,其中包含奇数位置元素和偶数位置元素。如何改进此代码

Prolog:获取一个包含两个子列表的列表,其中包含奇数位置元素和偶数位置元素。如何改进此代码,prolog,Prolog,我想问一下,是否有人知道如何改进(如果不是最优的)这段代码 想法是,你有一个元素列表,我想返回一个列表,其中有两个子列表,第一个子列表应该包含在列表奇数位置的元素,第二个子列表应该包含在列表偶数位置的元素 一些例子: ?-evenAndOdd([1,2,3,4,5],[[1,3,5],[2,4]]) True. ?-evenAndOdd([a,b,c,d,e],[[a,c,e],[b,d]]). True. 我实现的代码是下一个: evenAndOdd([],[]). evenAndOdd

我想问一下,是否有人知道如何改进(如果不是最优的)这段代码

想法是,你有一个元素列表,我想返回一个列表,其中有两个子列表,第一个子列表应该包含在列表奇数位置的元素,第二个子列表应该包含在列表偶数位置的元素

一些例子:

?-evenAndOdd([1,2,3,4,5],[[1,3,5],[2,4]])
True.

?-evenAndOdd([a,b,c,d,e],[[a,c,e],[b,d]]).
True.
我实现的代码是下一个:

evenAndOdd([],[]).

evenAndOdd([H|R],NL):-
    evenAndOddRec([H|R], [[],[]],1,NL).


evenAndOddRec([], [LOdd,LEven],_,[LOdd,LEven]).

evenAndOddRec([H|R],[LOdd,LEven],Pos,NL):-
    \+ even(Pos),
    !,
    NPos is Pos +1,
    append(LOdd,[H],NLOdd),
    evenAndOddRec(R,[NLOdd,LEven],NPos,NL).

evenAndOddRec([H|R],[LOdd,LEven],Pos,NL):-
    NPos is Pos + 1,
    append(LEven, [H], NLEven),
    evenAndOddRec(R,[LOdd, NLEven],NPos,NL).



even(N):-
    N mod 2 =:=0.

您可以在递归时隐式确定偶数和奇数值,方法是一次取两个元素(并考虑元素数为奇数时):


您可以在递归时隐式确定偶数和奇数值,方法是一次取两个元素(并考虑元素数为奇数时):


代码不是最优的一个症状是,如果您在-、+、+实例化模式中要求额外的解决方案,它将陷入困境:

?- evenAndOdd(X, [[1,3,5], [2,4,6]]).
X = [1, 2, 3, 4, 5, 6] ;
<time passes>
这适用于许多实例:

?- evenAndOdd([1,2,3,4,5,6], O, E).
O = [1, 3, 5],
E = [2, 4, 6].

?- evenAndOdd([1,2,3,4,5], O, E).
O = [1, 3, 5],
E = [2, 4] ;
false.

?- evenAndOdd(X, [1,3,5], [2,4]).
X = [1, 2, 3, 4, 5] ;
false.

?- evenAndOdd(X, [1,3,5], [2,4,6]).
X = [1, 2, 3, 4, 5, 6].

?- evenAndOdd(X, [1,3,5], [2,4,6,8]).
false.

?- evenAndOdd([1,2,3,4,5,6], X, [2,4,6,8]).
false.

?- evenAndOdd([1,2,3,4,5,6], X, [2,4,6]).
X = [1, 3, 5].

代码不是最优的一个症状是,如果您在-、+、+实例化模式中要求额外的解决方案,它将陷入困境:

?- evenAndOdd(X, [[1,3,5], [2,4,6]]).
X = [1, 2, 3, 4, 5, 6] ;
<time passes>
这适用于许多实例:

?- evenAndOdd([1,2,3,4,5,6], O, E).
O = [1, 3, 5],
E = [2, 4, 6].

?- evenAndOdd([1,2,3,4,5], O, E).
O = [1, 3, 5],
E = [2, 4] ;
false.

?- evenAndOdd(X, [1,3,5], [2,4]).
X = [1, 2, 3, 4, 5] ;
false.

?- evenAndOdd(X, [1,3,5], [2,4,6]).
X = [1, 2, 3, 4, 5, 6].

?- evenAndOdd(X, [1,3,5], [2,4,6,8]).
false.

?- evenAndOdd([1,2,3,4,5,6], X, [2,4,6,8]).
false.

?- evenAndOdd([1,2,3,4,5,6], X, [2,4,6]).
X = [1, 3, 5].

这看起来像是复制品,但我找不到,但这并不意味着它不是复制品。在使用<代码> [Load,LEven ] < /C>时,请考虑<代码> [Load,LEven .REST ] < /Cord>。换句话说,扔掉你的代码,从
[LOdd,LEven | Rest]
的概念开始构建你的谓词。这看起来像是重复的,但我找不到,但这并不意味着它不是重复的。在使用<代码> [Load,LEven ] < /C>时,请考虑<代码> [Load,LEven .REST ] < /Cord>。换句话说,扔掉代码,从
[LOdd,LEven | Rest]
的概念开始,并在此基础上构建谓词。