【问题标题】:Prolog - get the first list from a list of listsProlog - 从列表列表中获取第一个列表
【发布时间】:2010-10-30 22:50:51
【问题描述】:

我有一个列表,其中包含较小的列表,每个列表包含 2 个项目:

[[a,1],[b,2],[c,3]]  

我正在使用一个名为 take(1,L,R) 的函数从列表 L 中获取第一项并返回项目 R。获取函数的代码在这里:

take(0,X,X).
take(N,[H|T],[H|R]):- 
    N>0, M is N-1,
    take(M,T,R).  

目前运行可能如下所示:

1 ?- take(1,[[a],[b],[c]],Taken).
Taken = [[a], [b], [c]]

与输入相同!这对于“常规”1 级深度列表也是如此:

2 ?- take(1,[a,b,c],Taken).
Taken = [a, b, c]

问题:
你的问题是我怎样才能使结果看起来像:

1 ?- take(1,[[a],[b],[c]],Taken).
Taken = [a]

我想返回我发送的列表的前 N ​​项。

【问题讨论】:

  • 这看起来有点像家庭作业......
  • 第一个元素的索引最好使用0。

标签: prolog


【解决方案1】:

您的基本情况take(0, X, X). 完全按照它所说的去做——给定任何值X,结果是X。我认为您想说的是take(1, [H|T], H).(它产生列表的第一个元素)。

我认为您实际上追求的是take(0, _, [ ]).,当从任何列表中“获取” 0 个项目时,它会产生一个空列表。这适用于您现有的递归案例。

您说您要获取“列表的前 N ​​个项目”——这样的结果必须存储在 N 个项目的列表中。因此take(1, [a, b, c], Taken) 将产生Taken = [a],而不是Taken = a。同样,take(1, [[a], [b], [c]], Taken). 将产生Taken = [[a]].。特殊情况下的 take(1, ...) 表单只返回第一项(不将其包装在列表中)会破坏您的递归。

【讨论】:

  • 基本情况 take(0, X, X)。如果 N 为 0,则意味着总是返回输入,“你不想删除任何东西,给你”之类的东西。整个功能应该像“Take the N first items”一样工作
  • @shaungus:好的,我现在理解你原来的基本情况背后的想法,但它不适用于你的递归,它说“列表的 take(n) 是那个的头带有该列表尾部的 take(n-1) 的列表”——当 n-1 达到 0 时,take 应该是 0 个项目。您也可以将基本情况定义为take(1, [H|T], H).,不定义 take(0),如果这对您更有意义(在递归情况下,您需要将 N>0 子目标更改为 N>1)。我个人更喜欢让 take(0) 返回一个空列表,因为这很有意义并且对我来说似乎是有效的(“给我 0 个项目”)
  • 好吧,我可能有两种不同的思维方式,具体取决于我在函数中的位置,我现在可以看到 X)。无论如何,我得到了它的工作,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
  • 2017-03-27
  • 2019-08-01
  • 1970-01-01
  • 2020-07-31
相关资源
最近更新 更多