创建乘以 n 倍的元素列表

问题描述 投票:0回答:3

所以我的问题是这样的,我有一个谓词repete_el(El,N,L),其中El是一个元素,N是重复的次数,L是包含该元素重复N次的列表。

我的问题是,它没有重复该元素,而是给出了 false,我不明白为什么。

示例:

我的输出:

?- repete_el(a,3,L).
false

正确输出:

?- repete_el(a,3,L).
L = [a,a,a].

节目:

repete_el(El,0,[]) :- !.

repete_el(El,N,L) :- repete_el(El,N,L,[],N).

repete_el(El,N,L,L2) :- length(L2,C),
                        C =< N,
                        append(L2,[N],NL),
                        repete_el(El,N,L,NL).

顺便说一下,我只能迭代地执行此操作。

list prolog
3个回答
4
投票

您可以使用标准

findall/3
谓词和事实上的标准
between/3
谓词。例如:

| ?- findall(a, between(1,5,_), List).
List = [a, a, a, a, a]
yes

1
投票

这不起作用的原因是因为在您调用

repete_el/4
时,
L2
是一个自由变量,因此
length(L2, C)
将开始构建各种具有长度的列表。然后,您对列表
NL
进行递归调用,并额外添加一个元素,并且您要求该列表再次具有长度
C
(应再次小于
N
)。但最终
C
将大于
N
,因此谓词将失败。

你可以写这样的谓词:

repete_el(_, 0, []).  %% (1)
repete_el(X, N, [X|T]) :-        %% (2)
    N > 0,
    N1 is N-1,
    repete_el(X, N1, T).

我们在此说:

(1) 重复元素

0
次的列表是空列表;和 (2) 重复
X
,
N
次且
N
大于
0
的列表是以
X
开头,以重复
X
,
N-1
的列表结束次。


0
投票

我喜欢将

maplist/2
=/2
结合使用来实现此目的。例如,

| ?- length(L, 3), maplist(=(a), L).

L = [a,a,a]

yes
| ?- length(L, 9), maplist(=(abc), L).

L = [abc,abc,abc,abc,abc,abc,abc,abc,abc]

yes
| ?-
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.