List 反向列表

List 反向列表,list,prolog,reverse,List,Prolog,Reverse,我的prolog代码有问题。我需要反转列表中的所有原子元素 示例:[1,2[3,4]]->[[4,3],2,1] 我的解决方案: myReverse([], []). myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X). myReverse([], []) :- !. myReverse([H|T], X) :- !, myReverse(H, NewH), myReverse(T, NewT),

我的prolog代码有问题。我需要反转列表中的所有原子元素

示例:[1,2[3,4]]->[[4,3],2,1]

我的解决方案:

myReverse([], []).
myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X).
myReverse([], []) :- !.

myReverse([H|T], X) :-
    !,
    myReverse(H, NewH),
    myReverse(T, NewT),
    append(NewT, [NewH], X).

myReverse(X, X).
但它只给了我:[[3,4],2,1]
我想,如果不是原子的,我需要使用is_list函数和递归调用列表。。。但是我被卡住了。。。你们知道怎么写吗?

差不多了。考虑这个解决方案:

myReverse([], []).
myReverse([H|T], X) :- myReverse(T, RT), myAppend(RT, H, X).
myReverse([], []) :- !.

myReverse([H|T], X) :-
    !,
    myReverse(H, NewH),
    myReverse(T, NewT),
    append(NewT, [NewH], X).

myReverse(X, X).
第一个子句是基本大小写,它包含一个cut(
),用于排除由于最后一个子句而留下的选项

第二个子句反转头
H
,它可以是原子或列表。如果
H
是一个原子,则切割后的递归子目标将使用最后一个子句求值,原子将原封不动地通过。如果
H
是一个列表,则使用第二个子句对其求值,并且所有元素都被颠倒。下一个子目标对列表的其余部分(尾部,
T
)执行相同的操作,然后使用内置的
append/3
将其连接起来。请注意,新的head元素
NewH
是单数元素,因此需要根据对列表进行操作的
append/3
的定义,将其作为
[NewH]
添加到单例列表结构中

最后一个子句通过unchanged传递所有其他内容(即原子、数字等-任何不是列表或变量的内容)

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).

这里没有附加

什么是
spoj/3
?我熟悉SPhere Online Judge,但当谈到Prolog时,我就迷路了……我已经将它重命名为myAppend,函数连接两个列表并将结果保存到X。+1:这是一个很好的累加器版本,使用的堆栈空间比我提出的版本少(不是尾部递归)。如果在
revall/3
的第二个子句中将
H
更改为
[H | Hs]
而使用模式匹配,则甚至可以替换
is_list/1
调用(并保留剪切),那么根本不需要内置。