的名单我有我的Prolog的一个问题。我需要反转列表中的所有元素。反向名单
实施例:[1,2,[3,4] - > [[4,3],2,1]
我的解决办法:
myReverse([], []).
myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X).
但它仅给出我: [[3,4],2,1] 我想,我需要使用is_list函数和递归调用列表,如果它不是原子的......但我卡住了......你们知道如何写它吗?
的名单我有我的Prolog的一个问题。我需要反转列表中的所有元素。反向名单
实施例:[1,2,[3,4] - > [[4,3],2,1]
我的解决办法:
myReverse([], []).
myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X).
但它仅给出我: [[3,4],2,1] 我想,我需要使用is_list函数和递归调用列表,如果它不是原子的......但我卡住了......你们知道如何写它吗?
差不多。考虑此解决方案:
myReverse([], []) :- !.
myReverse([H|T], X) :-
!,
myReverse(H, NewH),
myReverse(T, NewT),
append(NewT, [NewH], X).
myReverse(X, X).
第一子句是基础情况,其中包括一个切口(!
)排除,因为最后一个子句的左选择。
第二个子句反转头H
,它可能是一个原子或列表。如果H
是一个原子,切割后的递归子目标用最后一个子句进行评估,并且原子通过不变。如果H
是一个列表,则使用第二个子句对其进行评估,并且所有元素都相反。下一个子目标与列表的其余部分(尾部,T
)完全相同,然后使用内置的append/3
最终连接。请注意,新的头元素NewH
是奇异的,所以需要添加到列表单结构[NewH]
为每append/3
里面定义的列表上运行。
最后一个条款通过了所有其他事物(即原子,数字等 - 不是列表或变量的任何东西)。
revall(L, Y) :-
revall(L, [], Y).
revall([], Y, Y).
revall([H|T], T2, Y) :-
is_list(H),!,
revall(H, Hr),
revall(T, [Hr|T2], Y).
revall([H|T], T2, Y) :-
revall(T, [H|T2], Y).
这里没有追加
+1:这是一个很好的累加器版本,并会使用更少的堆栈空间作为我提出的版本(这不是尾递归)。如果使用了模式匹配,而不是在'revall/3'的第二个子句中将'H'更改为'[H | Hs]',那么您甚至可以替换'is_list/1'调用内置插件将是必要的。 – sharky 2012-04-10 23:22:14
什么'SPOJ/3'?我熟悉的领域在线评测,但是当涉及到Prolog的,我迷路了...... – dasblinkenlight 2012-04-10 01:55:05
我已经重新命名为myAppend,功能连接两个列表,并保存结果到十 – nich 2012-04-10 02:10:45