我有以下程序:
% finds all members in sorted list L1 that are not in the sorted L2
% and puts them in NL
make_list(L1,L2,NL):-
make_list(L1,L2,NL,x).
make_list([],_,[],_):-!.
% X represents the last value parsed from L1
make_list(L1,[],L2,X):-!,
make_list(L1,[99999999],L2,X).
make_list([X1|L1],[X2|L2],[X3|NewL],Last):-
(
(X1<X2,
X1 \= Last,
X3=X1,!,
make_list(L1,[X2|L2],NewL,X1);
X1<X2,!,
make_list(L1,[X2|L2],[X3|NewL],X1)
)
);
(
X1=X2,!,
make_list(L1,[X2|L2],[X3|NewL],*)
);
make_list([X1|L1],L2,[X3|NewL],*).
我的问题是,当最后一个值相同时(即:?- make_list([1,2],[2],L).
),由于
make_list([X1|L1],L2,[X3|NewL],*).
和
make_list(L1,[X2|L2],[X3|NewL],*)
将包含至少一个变量(第3个列表)的列表传递给make_list([],_,[],_)
。有评论说该程序的功能。如何使代码完成它应该做的事情?
我还在这里问了一个关于相同但完全没有工作的代码的问题:How do parenthesis work?。
答案 0 :(得分:2)
在解决此问题时,您应该考虑六个相互排斥的案例:
这六种组合涵盖了您需要编写的规则。
前两种情况可由单一规则涵盖:
make_list([], _, []).
这意味着如果第一个列表为空,则无法添加到输出列表中。
第三种情况也很简单:如果第二个列表为空,则输出与第一个列表相同:
make_list(L1, [], L1).
第四种情况稍微不那么简单:如果头部统一,同时丢弃它们,并解决一个较小的子问题:
make_list([H|T1], [H|T2], NL) :-
make_list(T1, T2, NL).
第五个案例将第一个列表的头部插入到输出中,第六个案例跳过第二个列表的头部:
make_list([H1|T1], [H2|T2], NL) :-
H1 < H2,
make_list(T1, [H2|T2], N2),
NL = [H1|N2].
make_list([H1|T1], [H2|T2], NL) :-
H1 > H2,
make_list([H1|T1], T2, NL).
请注意,当第一个列表包含重复项时,此解决方案无法按预期工作,而第二个列表不包含相应元素的重复项。
答案 1 :(得分:1)
% finds all members in sorted list L1 that are not in the sorted L2
% and puts them in NL
make_list(L1,L2,NL):-
make_list(L1,L2,NL,x).
make_list([],_,[],_):-!.
% X represents the last value parsed from L1
make_list(L1,[],L2,X):-!,
make_list(L1,[99999999],L2,X).
此处的问题是NewL
为[X3|NewL]
,当L1
为空时,make_list([],_,[],_):-!.
失败,因为[X3|NewL]
无法分配[]
}
make_list([X1|L1],[X2|L2],NewL,Last):-
X1<X2,
X1 \= Last,
NewL = [X3|NewL2],X3=X1,
make_list(L1,[X2|L2],NewL2,X1),!
;
X1<X2,
make_list(L1,[X2|L2],NewL,X1),!.
make_list([X1|L1],[X1|L2],NewL,Last):-!,
make_list(L1,[X1|L2],NewL,Last).
接下来的两种情况是X1>X2
,X2
被忽略,X1
仅在X1=Last
make_list([X1|L1],[_|L2],NewL,X1):-!, % X1>X2
make_list(L1,L2,NewL,X1).
make_list([X1|L1],[_|L2],NewL,Last):- % X1>X2
make_list([X1|L1],L2,NewL,Last).