我有一个列表中的元素列表[1,2,+]
,我想将它们作为一个元素推送到堆栈上。我可以通过将它们放在方括号之间来做到这一点,但这会使括号出现在输出中。例如,我想将列表 [1,2,+] 的元素推入堆栈:
stack([1,2,+],S,Y).
在哪里stack
:
stack(T,S,[T|S]).
问题是,如果我将更多表达式压入堆栈,它们将有嵌套的括号。例如,我会得到[[+,1,2],[*,3,4]]
,但我想要[+,1,2,*,3,4]
。我怎样才能做到这一点?
我有一个列表中的元素列表[1,2,+]
,我想将它们作为一个元素推送到堆栈上。我可以通过将它们放在方括号之间来做到这一点,但这会使括号出现在输出中。例如,我想将列表 [1,2,+] 的元素推入堆栈:
stack([1,2,+],S,Y).
在哪里stack
:
stack(T,S,[T|S]).
问题是,如果我将更多表达式压入堆栈,它们将有嵌套的括号。例如,我会得到[[+,1,2],[*,3,4]]
,但我想要[+,1,2,*,3,4]
。我怎样才能做到这一点?
You can 'flatten' the list:
| ?- List = [[+,1,2],[*,3,4]], flatten(List, FlatList).
List = [[+,1,2],[*,3,4]]
FlatList = [+,1,2,*,3,4]
Prolog interpreters often include a list library which will have a flatten predicate, but here is one implementation (from SWI-Prolog's lists library):
flatten(List, FlatList) :-
flatten(List, [], FlatList0), !,
FlatList = FlatList0.
flatten(Var, Tl, [Var|Tl]) :-
var(Var), !.
flatten([], Tl, Tl) :- !.
flatten([Hd|Tl], Tail, List) :- !,
flatten(Hd, FlatHeadTail, List),
flatten(Tl, Tail, FlatHeadTail).
flatten(NonList, Tl, [NonList|Tl]).
我不完全理解你的问题以及总体目标是什么,但也许你想要这样的东西。
stack(el(X, Y, Z), StackTail, [X, Y, Z | StackTail]).
如果您的堆栈元素都是三元组,则不要将它们表示为三个元素的列表。这不节省空间。相反,将它们表示为 terms el/3
。
另外,我了解您不希望您的堆栈成为复杂术语的列表,而是原子术语的列表。上面的定义stack/3
将在 push 时解开该el/3
术语,并在 pop 时构建它。
向堆栈添加另外两个规则应该可以解决问题。
因为这看起来很像家庭作业,所以我不会给出一个列表,但是您需要一个新规则,其中第一个参数明确地是一个列表,其中的项目递归地添加到现有堆栈中。
如果你写过member/2
and append/2
,你应该没有问题。