0

我有一个列表中的元素列表[1,2,+],我想将它们作为一个元素推送到堆栈上。我可以通过将它们放在方括号之间来做到这一点,但这会使括号出现在输出中。例如,我想将列表 [1,2,+] 的元素推入堆栈:

stack([1,2,+],S,Y).

在哪里stack

stack(T,S,[T|S]).

问题是,如果我将更多表达式压入堆栈,它们将有嵌套的括号。例如,我会得到[[+,1,2],[*,3,4]],但我想要[+,1,2,*,3,4]。我怎样才能做到这一点?

4

3 回答 3

2

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]).
于 2009-10-30T13:00:22.530 回答
2

我不完全理解你的问题以及总体目标是什么,但也许你想要这样的东西。

stack(el(X, Y, Z), StackTail, [X, Y, Z | StackTail]).

如果您的堆栈元素都是三元组,则不要将它们表示为三个元素的列表。这不节省空间。相反,将它们表示为 terms el/3

另外,我了解您不希望您的堆栈成为复杂术语的列表,而是原子术语的列表。上面的定义stack/3将在 push 时解开该el/3术语,并在 pop 时构建它。

于 2009-10-30T13:26:15.443 回答
1

向堆栈添加另外两个规则应该可以解决问题。

因为这看起来很像家庭作业,所以我不会给出一个列表,但是您需要一个新规则,其中第一个参数明确地是一个列表,其中的项目递归地添加到现有堆栈中。

如果你写过member/2and append/2,你应该没有问题。

于 2009-10-30T13:48:47.863 回答