List 只有两个参数的列表是否可以反转?
在Prolog中,只有两个参数可以反转列表吗?例如:List 只有两个参数的列表是否可以反转?,list,prolog,List,Prolog,在Prolog中,只有两个参数可以反转列表吗?例如: reverse_list(List, Reversed). 这不是家庭作业,我在七周内阅读了七种编程语言,我很好奇 通过三个参数,您可以使用累加器(与函数式编程非常相似): 澄清:我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下实现这一点您可以编写一个带有两个参数的revu list函数: rev_list([], []). rev_list([Head|Tail], Reversed) :- r
reverse_list(List, Reversed).
这不是家庭作业,我在七周内阅读了七种编程语言,我很好奇
通过三个参数,您可以使用累加器(与函数式编程非常相似):
澄清:我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下实现这一点您可以编写一个带有两个参数的
revu list
函数:
rev_list([], []).
rev_list([Head|Tail], Reversed) :- rev_list(Tail, TailReversed),
append(TailReversed, [Head], Reversed).
如果在函数式编程中,您可能更熟悉此函数:
reverseList([], Accumulator, Accumulator).
reverseList([Head|Tail], Accumulator, Solution) :-
reverseList(Tail, [Head|Accumulator], Solution).
reverseList(List, Solution) :-
reverseList(List, [], Solution).
rev x::xs = rev xs @ [x]
但是,您应该注意到,3参数版本是首选的,因为它是尾部递归的。当然:
reverseList([[], Accumulator, Accumulator]).
reverseList([[Head|Tail], Accumulator, Solution]) :-
reverseList([Tail, [Head|Accumulator], Solution]).
reverseList([List, Solution]) :-
reverseList([List, [], Solution]).
编辑:实际上只有一个:b
非作弊方法:
reverse([],[]).
reverse([H|T],L):-
reverse(T,R),
append(R,[H],L).
问题是性能会很差:您将在列表上递归,并且对每个元素执行一个append/3。
使用时间/1和1000000个元素的随机列表:
accumulator: % 2,000,003 inferences, 0.652 CPU in 0.652 seconds (100% CPU, 3066292 Lips)
arity-2 % 1,000,003 inferences, 0.178 CPU in 0.178 seconds (100% CPU, 5602426 Lips)
我知道我要迟到了,但有一种方法可以做到这一点,而不必“作弊”或使用
append
:
rev([], []).
rev([Head], [Head]).
rev([Head|Tail], [RHead|RTail]) :-
rev(Tail, [RHead|RMid]),
rev(RMid, Mid),
rev([Head|Mid], RTail).
它不是很有效(
O(3^n)
time),但它很优雅,甚至可以用于定理证明。请不要在标题中添加伪标记。这就是标记的用途。我看到了一个带有append的解决方案,我想知道您是否可以在没有其他prolog函数的情况下完成它。@重复一下,因为它不使用任何外部函数,所以很容易看到它的功能。我使用了一个类,我记得我们让ACL2证明这个版本等同于追加版本和尾部递归版本。然后我们可以在我们的程序中使用高效的尾部递归方法,但是在证明程序正确性时,让ACL2用这个方法或附加方法(取决于哪个更方便)替换它。