我会通过比较第一个列表的第一个索引并向索引添加 2 来解决这个问题。但我不知道如何检查序言中的索引。 另外,我会创建一个计数器,当计数器为奇数时(如果我们从 0 开始计数),它会忽略列表中的内容。 你能帮助我吗? 例子: everyOther([1,2,3,4,5],[1,3,5]) 为 true,但 everyOther([1,2,3,4,5],[1,2,3]) 不是.
最佳答案
我们提供了三个逻辑上纯粹的定义,即使您只需要一个 - variatio delectat:)
两个相互递归谓词
list_oddies/2
和skipHead_oddies/2
:list_oddies([],[]). list_oddies([X|Xs],[X|Ys]) :- skipHead_oddies(Xs,Ys). skipHead_oddies([],[]). skipHead_oddies([_|Xs],Ys) :- list_oddies(Xs,Ys).
递归
list_oddies/2
和非递归list_headless/2
:list_oddies([],[]). list_oddies([X|Xs0],[X|Ys]) :- list_headless(Xs0,Xs), list_oddies(Xs,Ys). list_headless([],[]). list_headless([_|Xs],Xs).
使用 meta-predicate 的“一行”
foldl/4
与 Prolog lambdas 结合::- use_module(library(lambda)). list_oddies(As,Bs) :- foldl(\X^(I-L)^(J-R)^(J is -I,( J < 0 -> L = [X|R] ; L = R )),As,1-Bs,_-[]).
所有三种实现都避免创建无用的选择点,但它们的做法不同:
- #1 和 #2 使用第一个参数索引。
- #3 使用
(->)/2
和(;)/2
以逻辑上安全的方式——使用(<)/2
作为条件。
让我们看一下 @WouterBeek 给出的查询 in his answer !
?- list_oddies([],[]),
list_oddies([a],[a]),
list_oddies([a,b],[a]),
list_oddies([a,b,c],[a,c]),
list_oddies([a,b,c,d],[a,c]),
list_oddies([a,b,c,d,e],[a,c,e]),
list_oddies([a,b,c,d,e,f],[a,c,e]),
list_oddies([a,b,c,d,e,f,g],[a,c,e,g]),
list_oddies([a,b,c,d,e,f,g,h],[a,c,e,g]).
true. % all succeed deterministically
感谢logical-purity ,我们得到了逻辑上合理的答案——即使是最一般的查询:
?- list_oddies(Xs,Ys).
Xs = [], Ys = []
; Xs = [_A], Ys = [_A]
; Xs = [_A,_B], Ys = [_A]
; Xs = [_A,_B,_C], Ys = [_A,_C]
; Xs = [_A,_B,_C,_D], Ys = [_A,_C]
; Xs = [_A,_B,_C,_D,_E], Ys = [_A,_C,_E]
; Xs = [_A,_B,_C,_D,_E,_F], Ys = [_A,_C,_E]
; Xs = [_A,_B,_C,_D,_E,_F,_G], Ys = [_A,_C,_E,_G]
; Xs = [_A,_B,_C,_D,_E,_F,_G,_H], Ys = [_A,_C,_E,_G]
...
关于list - 如何比较序言中的两个列表,如果第二个列表由列表一的所有其他元素组成,则返回 true?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30036180/