Prolog-实施Eratosthenes筛的麻烦

时间:2020-10-06 19:45:04

标签: prolog sieve-of-eratosthenes

我正尝试在序言中编写一个程序,以查找所有限制为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已被实例化,并且其值无法更改。我曾尝试用其他方法解决此问题,但无法提出解决方案。

非常感谢您在正确方向上的指导!

1 个答案:

答案 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