我正尝试在序言中编写一个程序,以查找所有限制为N
的质数,我正在尝试使用Sieve of Eratosthenes来实现。我是Prolog的新手,所以我还没有真正掌握递归思考的技巧(您可能会在我的代码中看到它)。
尽管如此,我(或多或少)尝试在序言中实现该算法,但如您在此处看到的那样,并没有走太远:
allPrimes(N, Primes) :-
numlist(2, N, Numlist),
A is round(sqrt(N)),
foreach(between(2, A, _i), sift(_i, Numlist, Primes)).
sift(_i, Numlist, Primes) :-
findall(_j, (member(_j, Numlist), _j \== _i, (_j mod _i =:= 0)), L),
subtract(Numlist, L, Primes).
由于false
失败,我一直得到subtract(Numlist, L, Primes)
作为输出,我之所以对它失败的猜测是因为Primes
已被实例化,并且其值无法更改。我曾尝试用其他方法解决此问题,但无法提出解决方案。
非常感谢您在正确方向上的指导!
答案 0 :(得分:4)
实例化后不能更改素数列表。但是,如果未实例化(而不是您的情况),则可以进一步实例化其中的某些项目,并且您可能可以通过这种方式解决此问题。
以下是基于您的算法的递归解决方案:
this.feedSub = this.feedService.getAll().subscribe(results => {
this.allposts = results.sort((a, b) => a.dateCreated <= b.dateCreated ? 1 : -1);
this.allposts = this.allposts.filter((post) => {
return post.category.name.match(ev.detail.value);
});
});
因此,您构建了可能的整数列表并计算了终止号。然后,您调用采用第一个质数的递归过程allPrimes(N, Primes) :-
numlist(2, N, Numlist),
Stop is round(sqrt(N)),
allPrimes(Numlist, Stop, Primes).
allPrimes([N|Numlist], Stop, [N|Primes]):-
exclude(is_multiple(N), Numlist, MPrimes),
(N =< Stop -> allPrimes(MPrimes, Stop, Primes) ; Primes=MPrimes).
is_multiple(N, I):-
I mod N =:= 0.
,然后从列表中排除该数字的所有倍数,并使用其余元素递归调用自身。
完成递归操作后(基本情况是N是停止号),我们重新构建了素数列表。
样品运行:
allPrimes/3