我有像[1,2,+]
这样的列表中的元素列表,我想将它们作为一个元素推送到堆栈中。我可以通过将它们放在方括号之间来做到这一点,但这会使括号出现在输出中。例如,我想将列表[1,2,+]的元素推送到堆栈:
stack([1,2,+],S,Y).
stack
的位置:
stack(T,S,[T|S]).
问题在于,如果我将更多表达式压入堆栈,它们将具有嵌套括号。例如,我会得到[[+,1,2],[*,3,4]]
,但我想要[+,1,2,*,3,4]
。我怎么能做到这一点?
答案 0 :(得分:2)
你可以'压扁'列表:
| ?- List = [[+,1,2],[*,3,4]], flatten(List, FlatList).
List = [[+,1,2],[*,3,4]]
FlatList = [+,1,2,*,3,4]
Prolog解释器通常包含一个列表库,它将具有展平谓词,但这里有一个实现(来自SWI-Prolog的列表库):
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]).
答案 1 :(得分:2)
我不完全理解你的问题,总体目标是什么, 但也许你想要这样的东西。
stack(el(X, Y, Z), StackTail, [X, Y, Z | StackTail]).
如果您的堆栈元素都是三元组,那么不要将它们表示为三个元素的列表。这不是节省空间的。相反,将它们表示为术语el/3
。
另外,我知道您不希望您的堆栈成为复杂术语的列表,
但是原子术语列表。 stack/3
的上述定义将会解开
推送时的el/3
术语,弹出时会构建它。
答案 2 :(得分:1)
添加两个规则到堆栈应该可以解决问题。
由于这看起来很像家庭作业,我不会给出一个列表,但你需要一个新规则,其中第一个参数显式是一个列表,其中的项以递归方式预先附加到现有堆栈。
如果你写过member/2
和append/2
,那么你应该没有问题。