check/3 谓词从列表中获取替代元素 [英] check/3 predicate to get alternate elements from a list
问题描述
我有一个谓词 check/3
用作,例如,check(A,B,C)
.所有三个参数都是列表:
I have a predicate check/3
used as, e.g., check(A,B,C)
. All three arguments are lists:
C
是主列表A
包含具有奇数索引的项目B
包含具有偶数索引的项目
C
is the master listA
contains items which have an odd indexB
contains items which have an even index
例如
check([1,3],[2,4],[1,2,3,4]) % is true
check([1,2],[3,4],[1,2,3,4]) % is false
我试图只检查而不是创建两个具有偶数和奇数奇偶校验的列表.这是我写的程序:
I am trying to just check and not create two lists with even and odd parity. Here is the program I wrote:
check( [] , [] , [] ).
check( O , C , [O,_|C] ) :- check(O,C,A).
我试图通过从第三个列表中删除替代元素并将其放在第一个列表中同时将其余元素放在第二个列表中来解决它.但我发现如果我比较它们就足够了.但是我不知道如何在没有任何算术或内置谓词的情况下实现它.
I am trying to solve it by removing alternate elements from third list and put it in 1st list while placing the remaining elements in the second list. But I see that it's enough if I compare them. But I couldn't get an idea of how to implement it without any arithmetic or built in predicates.
推荐答案
根据元素在列表中的序数位置(它的*index),如果您将列表中的第一项计算为奇数(索引为 1),这应该是诀窍:
To partition a list C
into a list of odd and even elements based on the ordinal position of the element within the list (its *index), this should the trick, if you count the first item in the list as odd (having an index of 1):
check( [] , [] , [] ) . % the empty list has neither an even nor an odd element.
check( [O] , [] , [O] ) . % a list of length 1 has only an odd element
check( [O|Os] , [E|Es] , [O,E|Xs] ) :- % a list of length > 1 has both an even and an odd element
check(Os,Es,Xs) . % - park them on the respective lists and recurse down.
另一方面,如果您想将第一项计算为偶数(索引为 0),则没有太大区别:
If, on the other hand, you want to count the first item as even, (having an index of 0), it's not much different:
check( [] , [] , [] ) . % the empty list has neither an even nor an odd element.
check( [] , [E] , [E] ) . % a list of length 1 has only an even element
check( [O|Os] , [E|Es] , [E,O|Xs] ) :- % a list of length > 1 has both an even and an odd element
check(Os,Es,Xs) . % - park them on the respective lists and recurse down.
您也可以通过使用辅助谓词和一个标志来完成同样的事情:
You can also accomplish the same thing by using a helper predicate with a flag that toggles to indicate state:
check( Os , Es , Xs ) :- % to partition list C into odd and even components...
check( odd , Os , Es , Xs ) . % - just invoke the helper with an appropriate seed value.
check( _ , [] , [] , [] ) . % we're done when we hit the end of the list.
check( odd , [X|Os] , Es , [X|Xs] ) :- % otherwise, place the head of the source list on the odd result list
check( even , Os , Es ,Xs ) . % - and recurse down, toggling state to even.
check( even , Os , [X|Es] , [X|Xs] ) :- % otherwise, place the head of the source list on the even result list
check( odd , Os , Es ,Xs ) . % - and recurse down toggling state to odd.
您会注意到,在上面的示例中,我们用 odd
为辅助函数设置种子,以指示第一个元素具有奇数位置(1-相对).如果您希望第一个元素具有偶数位置(相对于 0),只需将种子值切换为 even
.
You'll note that in the above example, we've seeded the helper with odd
to indicate that the 1st element has an odd position (1-relative). Just switch the seed value to even
if you want the first element to have an even position (0-relative).
然而...有一个更简单的方法:在每次递归时,只需切换两个结果列表的位置:
However... There's a simpler way: on each recursion, just switch the position of the two result lists:
check( [] , [] , [] ) .
check( [X|As] , Bs , [X|Cs] ) :- check( Bs , As , Cs ) .
甜!
这篇关于check/3 谓词从列表中获取替代元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!