Prolog列表操作代码调试:输入含长度为0的元组列表时输出冗余空列表
解决Prolog extend谓词过滤空列表的问题
我来帮你搞定这个问题!你的代码现在会把所有输入元组都转换成对应的列表,包括N=0时生成的空列表,所以结果里才会出现[[], [], [c]]。要得到你想要的[[c]],我们只需要修改逻辑,跳过那些N=0的元组就行。
方案一:直接修改extend谓词
我们可以给extend加一个子句,专门处理N=0的情况——直接跳过这些项,不生成空列表到结果里:
extend([],[]). % 遇到N=0的元组,直接递归处理剩余列表,不添加任何元素到结果 extend([(0,_)|T], NewListT) :- extend(T, NewListT). % 只处理N>0的元组,生成对应列表并加入结果 extend([(N,L)|T], [NewList|NewListT]) :- N > 0, fill((N,L), NewList), extend(T, NewListT). fill((N,L), List) :- length(List, N), maplist(=(L), List).
测试这个修改后的代码:
?- extend([(0,a),(0,b),(1,c)], Result). Result = [[c]].
完全符合你的预期!
方案二:先过滤输入列表再处理
如果你不想修改原有的extend谓词,也可以先把输入列表中N=0的项过滤掉,再传给原来的extend处理:
% 过滤掉所有N=0的元组 filter_non_zero([], []). filter_non_zero([(0,_)|T], Filtered) :- filter_non_zero(T, Filtered). filter_non_zero([(N,L)|T], [(N,L)|Filtered]) :- N > 0, filter_non_zero(T, Filtered). % 你原来的extend和fill谓词保持不变 extend([],[]). extend([(N,L)|T], [NewList|NewListT]):- fill((N,L),NewList), extend(T,NewListT). fill((N,L),List) :- length(List, N), maplist(=(L), List).
使用时先过滤再处理:
?- filter_non_zero([(0,a),(0,b),(1,c)], Filtered), extend(Filtered, Result). Filtered = [(1, c)], Result = [[c]].
为什么原代码不符合预期?
你的原extend谓词会遍历输入列表的每一个元组,不管N的值是多少,都会调用fill生成对应的列表。当N=0时,fill会生成一个空列表,所以这些空列表就被包含在最终结果里了。我们的修改核心就是让N=0的元组不产生任何输出元素,从而得到你想要的结果。
内容的提问来源于stack exchange,提问作者user15734697
相关产品推荐
相关产品推荐

