Prolog如何制作新的数字列表

时间:2018-03-20 18:31:19

标签: prolog

我有一个原始列表,格式为[name+name+mark, name+name+mark] 而我想要做的是创建一个新的列表,其中只有标记为[mark1, mark2]的元素(标记为数字!)。所以我做了一个代码

getAvg([], NEWLIST).
getAvg([_+_+Mark|Xs], R) :-
    getAvg(Xs, T) ,
    append(T, [Mark], R).

但只有getAvg([susan+andy+43, susan+mike+43], A)返回的内容是

R = [43, 43] ;
R = [_2918, 43, 43] ;
R = [_2918, _2930, 43, 43] ;
R = [_2918, _2930, _2942, 43, 43] ;
R = [_2918, _2930, _2942, _2954, 43, 43] ;
R = [_2918, _2930, _2942, _2954, _2966, 43, 43] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, 43, 43] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, 43, 43] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, 43|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] ;
R = [_2918, _2930, _2942, _2954, _2966, _2978, _2990, _3002, _3014|...] 

我怎样才能让它只返回R = [43,43]

1 个答案:

答案 0 :(得分:4)

错误在于:

getAvg([], NEWLIST).

这应该是:

getAvg([], []).

因为空列表需要返回空列表。

虽然效率的另一点是规则:

getAvg([_+_+Mark|Xs], R) :-
    getAvg(Xs, T) ,
    append(T, [Mark], R).

你有了Mark,你继续使用列表的其余部分,最后你使用append遍历所有列表以添加Mark。一种更有效的方式是:

getAvg([_+_+Mark|Xs], [Mark,T]) :-getAvg(Xs, T).

在这里你不要遍历任何列表来添加马克只是将它放在头部。即使改变了最终列表的顺序,以这种方式执行它也会更有效率,并最终反转输出列表以获得与之前程序一样的精确行为。