这是我第一次尝试在非示例程序上对列表使用递归,请容忍我的经验不足!
预期有效查询:
mixElements([],[a,b,c], [a,b,c]).mixElements([a,b],[],[a,b]).mixElements([a,b,c],[d,e,f],[a,d,b,e,c,f]).mixElements([a,b,c],[d,e,f,g,h],[a,d,b,e,c,f,g,h]).
在这里,我尝试创建当输入列表为空时,简单返回结果的基本情况。
/* 基本情况 */mixElements([],[],Result).
我的递归语句的逻辑是,输入列表必须至少包含一个或多个元素。因此,它们都必须分别由[H|L]表示,用于列表1和列表2。然后它会将H1和H2附加到Result中,以创建列表元素的交替模式。最后,它会使用列表的剩余部分L1和L2,以及现在应该包含两个列表的第一个头元素的Result列表,调用mixElements。
/* 递归情况,其中L1和L2都不为空 */mixElements([H1|L1],[H2|L2],Result) :- append(H1,H2,Result), mixElements(L1,L2,Result).
我的结果输出总是“no”。
回答:
基本上这里有四种情况:
-
第一个列表为空,第二个列表为空,在这种情况下,结果应该是空的:
mixElements([],[],[]).
-
第一个列表为空,第二个列表非空,在这种情况下,结果是第二个列表:
mixElements([],[H2|T2],[H2|T2]).
-
第一个列表非空,第二个列表为空,在这种情况下,结果是第一个列表:
mixElements([H1|T1],[],[H1|T1]).
-
最后两个列表都非空,在这种情况下,结果的前两个元素是列表的头部,然后是列表尾部的混合:
mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :- mixElements(T1,T2,TT).
现在我们可以将这些整合成:
mixElements([],[],[]).mixElements([],[H2|T2],[H2|T2]).mixElements([H1|T1],[],[H1|T1]).mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :- mixElements(T1,T2,TT).
现在我们已经创建了一些冗余语句。例如,我们可以将前两个语句合并成一个,如下所示:
mixElements([],L,L).mixElements([H1|T1],[],[H1|T1]).mixElements([H1|T1],[H2|T2],[H1,H2|TT]) :- mixElements(T1,T2,TT).
我将其作为一个练习来进一步改进谓词。你可以使用剪切,但这可能会消除谓词的多方向性,这有时非常有用。