问题描述
我正尝试在序言中编写一个程序,以查找所有限制为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,Primes) :-
findall(_j,(member(_j,_j \== _i,(_j mod _i =:= 0)),L),subtract(Numlist,L,Primes).
由于false
失败,我一直得到subtract(Numlist,Primes)
作为输出,我之所以对它失败的猜测是因为Primes
已被实例化,并且其值无法更改。我曾尝试用其他方法解决此问题,但无法提出解决方案。
非常感谢您在正确方向上的指导!
解决方法
实例化后不能更改素数列表。但是,如果未实例化(而不是您的情况),则可以进一步实例化其中的某些项目,并且您可能可以通过这种方式解决此问题。
以下是基于您的算法的递归解决方案:
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],[N|Primes]):-
exclude(is_multiple(N),Numlist,MPrimes),(N =< Stop -> allPrimes(MPrimes,Primes) ; Primes=MPrimes).
is_multiple(N,I):-
I mod N =:= 0.
,然后从列表中排除该数字的所有倍数,并使用其余元素递归调用自身。
完成递归操作后(基本情况是N是停止号),我们重新构建了素数列表。
样品运行:
allPrimes/3