【问题标题】:Prolog: split a list into a list of N lists containing N items eachProlog:将一个列表拆分为一个包含 N 个列表的列表,每个列表包含 N 个项目
【发布时间】:2016-01-25 16:53:11
【问题描述】:

我一直在搜索与拆分相关的许多现有 Prolog 问题,但找不到像我想要的那样通用的问题。我想指出,我已经能够通过使用在列表变量之前通过管道传输的 2/3/4 变量将列表拆分为 2/3/4 个元素的列表。这个问题与那个问题不同,只是因为它的通用性。

所以,我的列表将始终包含 N*N 项,N 是事先未知的(通常从 4 到 36 不等,是的,N 也是一个完美的正方形)。我想将它拆分为一个包含 N 个项目的 N 个列表的列表,因为这将允许我将其视为一个矩阵,从而允许转置和某些此类操作。因为我对声明式编程比较陌生,所以我还没有真正能够在逻辑上走得太远。请看下面我的不完整(错误)尝试:

listmodel(1,L):- L = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16].
size(L,N) :- length(L,N1), N is round(sqrt(N1)).

% add_tail(+Liste, +Element, -ResultantList)
add_tail([],L,[L]).
add_tail([X|L1],L2,[X|LI]):-add_tail(L1,L2,LI).

% partition the list containing N*N items into a list of N lists containing N elements each.
% part(+Liste, +Size, -ResultantList)
part([],_,DL).
part(L,N,DL) :-
    length(P,N), % P(refix) initialized
    append(P,S,L), % S(uffix) contains rest of L, using append in (-,-,+) mode
    add_tail(DL,P,DL1), %add P(first N elements) as first element of DL.
    part(S,N,DL1).

现在运行?- listmodel(1,L),size(L,N),part(L,N,DL). 将产生DL=[],因为这是它在part 谓词中的第一个add_tail 调用中被初始化的内容。我似乎无法弄清楚如何将所有元素存储在通过递归保留的列表中。

任何帮助/指导将不胜感激。我被困在这里已经超过 23 小时 10 分钟了。

谢谢。

【问题讨论】:

    标签: list prolog sudoku declarative


    【解决方案1】:

    应该这样做:

    部分([], _, [])。 部分(L,N,[DL|DLTail]):- length(DL, N), append(DL, LTail, L), 部分(LTail,N,DLTail)。

    基本情况是第一个/最后一个参数是空列表。

    递归步骤获取一个新的 N 个元素列表,从 L 中获取前 N 个元素(这将是第三个参数的项之一)并递归调用。

    【讨论】:

    • 完美!感谢您的准确回答和简洁的解释。
    【解决方案2】:

    想要结合多功能性有利的端接特性? 使用

    :- use_module(library(clpfd))。

    首先,我们定义 list_prefix_n_suffix/4list_prefix_n_suffix(Zs,Xs,N,Ys) 在逻辑上等同于@987654324@(Xs,Ys,Zs), @987654325@(Xs,N)@987654326@(Xs,N), @987654327@(Xs,Ys,Zs),但比任何一个1 一个更好的通用终止行为!

    list_prefix_n_suffix(Zs, Xs, N, Ys) :- list_prefix_n0_n_suffix(Zs, Xs, 0,N, Ys)。 list_prefix_n0_n_suffix(Zs, Xs, N0,N, Ys) :- zcompare(订单, N0, N), rel_list_prefix_n0_n_suffix(顺序,Zs,Xs,N0,N,Ys)。 rel_list_prefix_n0_n_suffix(=, Ys, [], _,_, Ys)。 rel_list_prefix_n0_n_suffix( #= N0 + 1, list_prefix_n0_n_suffix(Zs, Xs, N1,N, Ys)。

    list_prefix_n_suffix/4 的一些示例查询:

    ?- list_prefix_n_suffix([a,b,c], Xs,-1, Ys)。 错误。 % OK:太小了 ?- list_prefix_n_suffix([a,b,c], Xs, 0, Ys)。 Xs = [],Ys = [a,b,c]。 % 确定性地成功 ?- list_prefix_n_suffix([a,b,c], Xs, 4, Ys)。 错误。 % OK:太大 ?- list_prefix_n_suffix([a,b,c], Xs, N, Ys)。 Xs = [],N = 0,Ys = [a,b,c] ; Xs = [a] , N = 1, Ys = [b,c] ; Xs = [a,b] , N = 2, Ys = [c] ; Xs = [a,b,c], N = 3, Ys = [] ;错误的。 % 普遍终止

    基于上述list_prefix_n_suffix/4,我们定义list_rows_width/3

    列表行宽度([],[],_N)。 list_rows_width([E|Es0], [[R|Rs]|Rss], N) :- list_prefix_n_suffix([E|Es0], [R|Rs], N, Es), list_rows_width(Es,Rss,N)。

    使用list_rows_width/3的示例查询:

    ?- list_rows_width([a,b,c,d,e,f], 行, 4)。 错误的。 % OK:6 不能被 4 整除 ?- list_rows_width([a,b,c,d,e,f], 行, 3)。 行 = [[a,b,c],[d,e,f]]。 % 确定性地成功 ?- list_rows_width([a,b,c,d,e,f,g,h,i,j,k,l], 行, N)。 N = 1, 行 = [[a],[b],[c],[d],[e],[f],[g],[h],[i],[j],[k] ,[l]] ; N = 2, 行 = [[a, b],[c, d],[e, f],[g, h],[i, j],[k, l]] ; N = 3, 行 = [[a, b, c],[d, e, f],[g, h, i],[j, k, l]] ; N = 4,行 = [[a, b, c, d],[e, f, g, h],[i, j, k, l]] ; N = 6,行 = [[a,b,c,d,e,f],[g,h,i,j,k,l]] ; N = 12,行 = [[a,b,c,d,e,f,g,h,i,j,k,l]] ;错误的。 % 普遍终止

    按应有的方式工作!


    脚注 1: 不求助于使用替代控制流机制,如

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      • 2012-10-04
      相关资源
      最近更新 更多