【问题标题】:Copy all the elements of one list N times in a new list Prolog将一个列表的所有元素复制 N 次到一个新列表 Prolog
【发布时间】:2019-12-15 17:32:50
【问题描述】:

如何在不使用 Maplist、findall 或库的情况下使用 Prolog 的简单命令将一个列表的所有元素复制到一个新列表中 N 次。

例如我问 Prolog 的查询:

?- copy_list([a,b,c,d],3,List).

该查询的答案类似于:

List = [a,b,c,d,a,b,c,d,a,b,c,d].

【问题讨论】:

  • 你尝试了什么,什么不起作用?
  • 我尝试递归地做到这一点,我在列表中得到了许多具有相同元素的列表 List=[ [a,b,c,d],[a,b,c,d],[ a,b,c,d] ]。
  • 我知道 append 我已经尝试过了,但没有成功
  • 不,那可能是append/3,这是append/2

标签: prolog


【解决方案1】:

我们可以先生成一个N 子列表的列表,然后用append/2 [swi-doc] 展平该列表:

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

那么我们可以将copy_list/3 谓词定义为:

copy_list(L, N, R) :-
    copy_list(N, L, LL),
    append(LL, R).

或者我们可以在这里使用append/3 [swi-doc],因此每次都会减少数字,并且

copy_list(_, 0, []).
copy_list(L, N, R) :-
    N > 0,
    N1 is N-1,
    copy_list(L, N1, R2),
    append(L, R2, R).

【讨论】:

  • 非常感谢!我会用最后一个!
  • @hellfireworld 你说“没有图书馆”,但追加来自library(lists)
【解决方案2】:

Willem 的第一个解决方案的一个转折点:

copy_list(L, N, Copies) :-
    length(Lists, N),           % List of length N
    maplist(=(L), Lists),       % Each element of Lists is unified with L
    append(Lists, Copies).      % Lists is flattened

7 ?- copy_list([a,b,c], 3, L).
L = [a, b, c, a, b, c, a, b, c].

8 ?-

对于违反 OPs 原始“不使用 Maplist、findall 或库”规则表示歉意。我认为maplistlengthappend 是 Prolog 领域的基础。

【讨论】:

    【解决方案3】:

    “没有maplistfindall 或库”:

    copy_list(  _,     0,    []).
    copy_list( Xs,     I,    Ys) :- I > 0, copy_list(
               Xs,     I,    Ys,  Xs ).
    
    copy_list( Xs,     1,    Xs,  _  ).
    copy_list( [X|Xs], I, [X|Ys], Xs0) :- I > 1, copy_list(Xs,  I,  Ys, Xs0).
    copy_list( [],     I,    Ys , Xs0) :- I > 1, I1 is I-1, 
                                                 copy_list(Xs0, I1, Ys, Xs0).
    

    【讨论】:

    • s(x)... Dang 我有时会瞥一眼那些 OP 提出的关于“没有库”的 cmets,尽管接受的答案使用 append/3。 :)
    • "虽然被接受..." 是的。 :/ 所以你也不应该删除你的。 :)
    • 这是一个非常好的解决方案。我建议在示例中使用 clpfd:clpfd 的推广对于 Prolog 非常重要。
    • 使用XsYs 代替XY 会大大提高该解决方案的清晰度。
    • 令人困惑的是arity从copy_list(X,I,Y)copy_list(X,X2,I,Y)的增长。它应该是 copy_list(X2,X,I,Y)copy_list(X,I,Y,X2)(X,I,Y) 原来的三巨头应该保持下去。
    猜你喜欢
    • 2018-01-11
    • 1970-01-01
    • 2018-03-11
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多