首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >递归谓词的输出

递归谓词的输出
EN

Stack Overflow用户
提问于 2019-02-28 23:16:45
回答 1查看 50关注 0票数 0

以下谓词的目标是选择列表的前N项。这应该被赋值给输出变量,但事实并非如此。

代码语言:javascript
复制
firstx(N, [H|T], L) :-
    (
        length(L, Le), Le < N ->
        append(L, [H], O),
        firstx(N, T, O)
    ;
        write(L)
    ).

这是上述谓词的输出

代码语言:javascript
复制
?- firstx(2, [1,2,3,4,5], X).
[1,2],
X = [].

这就是它应该是的

代码语言:javascript
复制
?- firstx(2, [1,2,3,4,5], X).
[1,2],
X = [1,2].

如图所示,最后一个变量没有正确赋值。你对它应该如何编程有什么建议吗?提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-28 23:32:34

我被你写的代码搞糊涂了。我在firstx(N, T, O)中看不到递归的基本情况。N永远不会减少,尽管您在第二个位置从列表中剥离了项,但当该列表为空时,您没有理由这样做。您使用append/3似乎是为了将项目放在结果列表的末尾,但您也在构造L。最终,我认为您的问题可能与以下事实有关:您正在将第三个参数的新变量传递给递归调用(它最终会将其写出),但您返回的不是O,而是L。我猜如果用O替换L,这就不起作用了,因为在开始查询时必须取消实例化变量,但在递归调用中实例化了它。

我真的不知道你想用这段代码做什么。我看到了两种明确的实现方法:递归谓词,或者使用append/3,我在您的解决方案中看到了这两种方法的元素。因此,让我与您分享我所看到的两种方法。

递归方法将如下所示:

代码语言:javascript
复制
firstx(0, _, []).
firstx(N1, [H|T], [H|R]) :- 
    succ(N0, N1), 
    firstx(N0, T, R).

在这个解决方案中,我们将列表头部的项逐个放入结果中。使用succ/2是一个很好的习惯,因为与N0 is N1 - 1不同的是,它实际上是双向工作的。当我在你的子句开头看到[H|T]的时候,我想这就是你要说的,但是我还是怀疑你没有以类似的方式构建L,也没有在你的递归调用中减少N

append/3方法将如下所示:

代码语言:javascript
复制
firstx(N, L, FirstN) :- 
    length(FirstN, N),
    append(FirstN, _, L).

这是一个更优雅的解决方案,因为您可以使用length/2创建任意长度的变量列表,然后让append/3为您完成所有的统一工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54928883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档