【问题标题】:I am having problems getting a list of lists into a single list我在将列表列表放入单个列表时遇到问题
【发布时间】:2019-04-04 10:39:36
【问题描述】:

我正在编写一个使用递归计算列表中数字之间距离的解决方案,但一直在努力获得预期的输出。 我正在尝试将列表列表放入单个列表中,但尝试使用 flatten 和 append/2 不起作用。我已经尝试了几个小时,并且一直在转圈,有人可以告诉我我做错了什么吗?

:- use_module(library(clpfd)).

difference([],_,[]).
differwnce([L|Ls],X,[DST|Ds]) :-
   DST #= abs(X - L),
   difference(Ls,X,Ds).

differences[],[]).
differences([L|Ls], [DST|Tail]) :-
   difference(Ls,X,DST),
   differences(Ls, Tail).

这是预期的输入和输出:-

?- differences([1,2,4,9],Ds).
Ds = [1,3,8,2,7,5].

电流输出:

Ds = [[1,3,8],[2,7],[5],[]].

【问题讨论】:

  • 请在问题中包含您的代码,以便我们查看您的尝试
  • 对不起,我是在 Stackoverflow 上发布问题的新手,对格式有点困惑。现在应该起来了。谢谢。
  • 回滚您删除的代码,因为它特定于问题。您的代码在示例中使用了约束,因此使答案更加具体。通过删除代码,阅读本文的初学者可能会认为约束是必需的,而实际上不是。
  • 这能回答你的问题吗? Get elements from list of lists

标签: prolog


【解决方案1】:
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

seqq([]) --> [].
seqq([Es|Ess]) -->
  seq(Es),
  seqq(Ess).

?- phrase(seqq([[1,3,8],[2,7],[5],[]]), Es).
Es = [1,3,8,2,7,5].

?- dif(A,B), phrase(seqq([[A|_]|_]), [B|_]).
false.

【讨论】:

  • 对不起,这让我更加困惑。我是 swi prolog 的初学者,请问有更简单的解决方案吗?
  • 你好假,你的意思是设置另一个谓词来手动转换列表吗?像 append/2 通常一样吗?你能告诉我为什么 append/2 在我的情况下不起作用吗?
【解决方案2】:

您可以将distances/3 谓词转换为distances/4 谓词,该谓词返回后面的元素的列表尾部,有效地使用打开列表

:- use_module(library(clpfd)).

distances([], _, Tail, Tail).
distances([BN| Bs], B, [DST| Ds], Tail) :-
   DST #= abs(B - BN),
   distances(Bs, B, Ds, Tail).

triangle([], []).
triangle([BN| Bs], Ds) :-
    distances(Bs, BN, Ds, Tail),
    triangle(Bs, Tail).

示例调用:

?- triangle([1,2,4,9], Ds).
Ds = [1, 3, 8, 2, 7, 5].

为了更好地理解此解决方案,请考虑以下查询的结果:

?- distances([2,4,9], 1, Ds, Tail).
Ds = [1, 3, 8| Tail].

这种解决方案比在末尾调用 append/2flatten/3 等谓词更有效。

附:如果您仍然需要在其他地方使用 distances/3 谓词,您可以轻松定义它:

distances(Bs, B, Ds) :-
    distances(Bs, B, Ds, []).

【讨论】:

  • 非常感谢 Paulo 我会试试这个。我唯一的问题是我只能使用 distances/3 谓词。但是,我也可以使用您的建议设置另一个?还是有其他方法可以保持距离/3?
  • @AntMan 您可以使用distances/4 轻松定义distances/3distances(Bs,B,Ds) :- distances(Bs,B,Ds,[]).。这对你有用吗?
  • 完美的保罗,谢谢!这让我困了这么多小时。在三角形递归调用之后,我试图使用 append(ds, DST) 很长时间,但它只是不会将它放入单独的列表中。你知道这是为什么吗?这是不合逻辑的大声笑,因为 append/2 应该采用列表列表并连接到一个列表中
  • @AntMan 请注意,我的答案比任何调用附加或展平谓词的解决方案都更有效。
  • 太棒了。昨天我还尝试了不同的方法来制作另一个列表并手动将元素放入几个小时,但它只是不起作用。试图了解它仍然是如何工作的.. 额外的 Tail 正在将呼叫中剩下的任何东西带到距离?我有点困惑,但很好用
【解决方案3】:

为什么不像这样使用库谓词append/2

?- append([[1,3,8],[2,7],[5],[]], Xs).
Xs = [1,3,8,2,7,5].

【讨论】:

  • @repeat 我无法让它与我的代码一起使用,我不知道为什么。那是我最初的问题
  • 它不喜欢在 append 中使用 Ds,即使它是我假设的列表列表
  • 使用append/2: 在最后一次作为快速修复,而不是在递归子句中。
  • 它需要在递归谓词内或至少从递归谓词中调用另一个谓词来追加。我也无法让它以这种方式工作。我认为我需要更多地了解 prolog 基础知识以了解原因
  • 为什么不像这样使用库谓词 append/2? 因为 append/2 会产生许多不必要的错误,例如 dif(A,B), append([[A|_]|_], [B|_]).,这些错误可能会静默失败
猜你喜欢
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 2019-03-11
相关资源
最近更新 更多