Prolog - 从嵌套列表中提取数字

时间:2013-01-17 23:02:45

标签: prolog

我尝试编写一个函数getNumbers(List,Result),使得List是一个列表,其元素可以是整数或列表列表,例如 -

List = [1,[1,2,[3],[4]],2,[4,5]]
List = [1,[1,1,[1],[1]],1,[1,1,[[[[[1]]]]]]]
List = [[4,[[]],2],[[1],[],[1]]]
etc..

输出应该是List中存储的所有数字,例如 -

?- getNumbers([1,[1,2,[3],[4]],2,[4,5]],R).
R = [1,2,3,4,5].
?- getNumbers([1,[1,1,[1],[1]],1,[1,1,[[[[[1]]]]]]],R).
R = [1].
?- getNumbers([],R).
R = [].
?- getNumbers([[4,[[]],2],[[1],[],[1]]],R).
R = [1,2,4].

到目前为止,我尝试了以下代码 -

getNumbers([],Result) :- Result=[],!.
getNumbers([H|Rest],Result) :- getNumbers(Rest,NewResultRest),
    ( atomic(H) ->  
      Result = [H|NewResultRest]    
    ; getNumbers(H,NewResultHead),Result = [NewResultHead|NewResultRest]    ).

但它给出了错误的结果,比如 -

 getNumbers([[2],5,7,[3,6,5]],Result).
Result = [[2], 5, 7, [3, 6, 5]].

该函数似乎不会从2中排除[2]或嵌套列表中存储的任何其他数字。

我如何修复我的实施?

1 个答案:

答案 0 :(得分:1)

你需要附加嵌套列表:

getNumbers([],Result) :- Result=[],!.
getNumbers([H|Rest],Result) :-
    getNumbers(Rest,NewResultRest),
    (  atomic(H)
    -> Result = [H|NewResultRest]
    ;  getNumbers(H,NewResultHead),
       append(NewResultHead, NewResultRest, Result) % only this change
    ).

请注意[]是原子的:因此

?- getNumbers([[4,[[]],2],[[1],[],[1]]],R).
R = [4, [], 2, 1, [], 1].

从您的描述中,您应该使用数字/ 1来测试元素的类型。改变后

?- getNumbers([[4,[[]],2],[[1],[],[1]]],R).
R = [4, 2, 1, 1].