recursion - 不使用列表的 Prolog 谓词
问题描述
我需要在count(X,Y,D,N)
不使用列表的情况下编写序言谓词,该列表应该计算两个整数之间的元素数,包括两个X
整数Y
。但是,它应该只计算那些可以被 整除的值D
。
例如,count(3,6,2,N)
应该返回N = 2
,因为 4 和 6 可以被 2 整除,但 3 和 5 不能。
解决方案
递归是你的朋友(就像大多数 Prolog 的情况一样)。
一个辅助谓词接受一个作为累加器的附加参数在这里很有用:
这样的事情应该做你:
count( X, Y, D, N ) :- count( X, Y, D, 0, N ) .
count( X , Y , D , T , N ) :- X =< Y, % If X <= Y ...
( X rem D =:= 0 % - and X is divisible by D
-> T1 is T+1 % - then increment T
; T1 = T % - otherwise don't
), % and
X1 is X+1, % - increment X
count( X1, Y, D, T1, N ). % - recurse down
count( X , Y , _ , N , N ) :- X > Y. % IF X > Y, we're done: unify the accumulator with the result.
以上是尾递归的,并且出于所有意图和目的而优化为迭代。更经典的递归解决方案是这样的:
count( X, Y, _, 0 ) :- X > Y .
count( X, Y, D, N ) :- X =< Y ,
X1 is X+1,
count( X1, Y, D, T ),
( 0 =:= X rem D -> N is T+1 ; N = T )
.
推荐阅读
- amazon-web-services - 在 Cloud Formation 中为 SQS 创建 VPC 接口端点
- ios - 如何从我的 Xcode 调试器中读取此语句?
- java - 从 sqlite 获取数据并存储在 json 中
- azure-devops - 如何从 azure 管道任务插件中获取 auzre cosmos db 数据并将其用于进一步的管道任务
- java - 如何在java中运行for循环?
- javascript - Yii2-如何在javascript中隐藏下拉列表中的值
- c# - Asp.Core 通过数据库中的 PGP_SYM_ENCRYPT 映射加密数据
- php - PHP mysqli 在调用存储过程时没有捕获一些错误
- azure - 如何在 Azure 中一次启动多个虚拟机
- google-cloud-firestore - 将 AWS AppSync 与 Firestore 用于可扩展的聊天应用程序的优缺点是什么?