list Prolog 创建列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10202666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Prolog Create a List
提问by xKalelX
I have to create list of n elements for example,
例如,我必须创建 n 个元素的列表,
do_list(5,L1).
should return,
应该回来,
L1=[1,2,3,4,5].
This is what I have, but it's not working.
这就是我所拥有的,但它不起作用。
do_list(X,L1):- X1 is X-1, do_list(X1,[X1|L1]).
do_list(0,[]).
回答by gusbro
If you want to create a list of consecutive numbers from 1 to N you can use builtin predicates findall/3
and between/3
this way:
如果你想创建一个从 1 到 N 的连续数字列表,你可以使用内置谓词findall/3
,between/3
这样:
do_list(N, L):-
findall(Num, between(1, N, Num), L).
?- do_list(5,L).
L = [1, 2, 3, 4, 5].
SWI also has another builtin which does just that, numlist/3
:
SWI 还有另一个内置函数可以做到这一点numlist/3
:
?- numlist(1,5,L).
L = [1, 2, 3, 4, 5].
回答by twinterer
There are three problems with your code. The first problem is that you add X1 to the list in the clause body, but you never pass the new list back towards the head of the clause. I.e., L1 is an accumulator variable, but you need a third argument that will be bound to the final list.
您的代码存在三个问题。第一个问题是您将 X1 添加到子句主体中的列表中,但您从未将新列表传递回子句的头部。即,L1 是一个累加器变量,但您需要将绑定到最终列表的第三个参数。
The second is that the second clause only matches if the input list is empty. This will never be the case, since you add X1 to the list before calling do_list/2
recursively. I.e., you don't have a recursion anchor, and the goal ?- do_list(5,L)
will never return.
第二个是第二个子句仅在输入列表为空时才匹配。永远不会是这种情况,因为您在do_list/2
递归调用之前将 X1 添加到列表中。即,您没有递归锚点,目标?- do_list(5,L)
将永远不会返回。
The third problem is that you add X1 to the list instead of X. You'd skip the largest number.
第三个问题是您将 X1 而不是 X 添加到列表中。您将跳过最大的数字。
This is how it should work:
这是它应该如何工作:
do_list(N, L) :- do_list1(N, [], L).
do_list1(0, L, L) :- !.
do_list1(N, R, L) :- N > 0, N1 is N-1, do_list1(N1, [N|R], L).
回答by TGar
Or if you don't want to use any built-in function (like me, when I tried this as a practice and then run into this question), you can use this (working but not effective) solution:
或者,如果您不想使用任何内置函数(像我一样,当我尝试将其作为练习然后遇到此问题时),您可以使用此(有效但无效的)解决方案:
connect([],X,X).
connect([H|T],C,[H|T2]) :- connect(T,C,T2).
revert([],[]).
revert([H|T],R) :- revert(T,Trev), connect(Trev,[H],R)
do_revlist(0,[]).
do_revlist(X,[X|L]) :- X1 is X-1, do_revlist(X1,L).
do_list(X,L2) :- do_revlist(X,L), revert(L,L2).
P.S. Works only for positive integers.
PS 仅适用于正整数。
回答by Henry Dorsett
Another solution similar to that of twinterer but without cut or predefined predicates, employing an accumulator.
另一种类似于 twinterer 的解决方案,但没有剪切或预定义谓词,使用累加器。
do_List(Max,L) :- do_ListAcc(1,Max,L). % call Accumulator
do_ListAcc(N,N,[N]). % N=:=N ends recursion
do_ListAcc(Min,Max,[Min|Succs]) :-
Next is Min + 1,
do_ListAcc(Next,Max,Succs).
This also works only for positive integers.
这也仅适用于正整数。