Sieve of Eratosthenes without arrays?

泪湿孤枕 提交于 2019-12-02 07:08:49

I'm taking back what I said earlier. Here it is, the "sieve" without arrays, in Haskell:

sieve limit = [n | n <- [2..limit], null [i | i <- [2..n-1], j <- [0,i..n], j==n]]

It is a forgetful sieve, and it is very very inefficient. Uses only additions, and integer comparisons. The list comprehensions in it can be re-coded as loops, in an imperative language. Or to put it differently, it moves counts like a sieve would, but without marking anything, and thus uses no arrays.

Of course whether you'd consider it a "true" sieve or not depends on what is your definition of a sieve. This one constantly recreates and abandons them. Or you could say it reimplements the rem function. Which is the same thing to say, actually, and goes to the essence of why the sieve suddenly becomes so efficient when reuse - via arrays usually - becomes possible.

The Sieve is about remembering the primes you found already. As far as I know there is no way to do this without arrays or lists and only with loops.
I checked some of the examples at RosettaCode at random and did not find one without an array and only loops.

If you add Classes and Methods as options you can come up with a recursive design:

public class Sieve
{

    private int current;
    private int max;
    private Sieve   parent;

    public Sieve(int current, int max, Sieve parent )
    {
        this.current = current;
        this.max = max;
        this.parent = parent;
    }

    public static void main(String[] args)
    {
        int n = 100;

        System.out.print("Primes from 1 to " + n + ":\n");

        printPrimes(n);
    }

    private static void printPrimes(int i)
    {
        new Sieve(2,i,null).start();    
    }

    private void start()
    {
        if(current <2 || max <2)
        {
            return;
        }

        if(this.current > max)
        {
            parent.print();
            return;
        }

        for(int i = this.current+1;current<=max+1;i++)
        {
            if(this.testPrime(i))
            {
                new Sieve(i,this.max,this).start();
                return;
            }
        }
    }

    private boolean testPrime(int i)
    {
        if(i%this.current != 0)
        {
            if(this.parent == null)
            {
                return true;
            }
            else
            {
                return this.parent.testPrime(i);
            }
        }
        return false;
    }

    private void print()
    {
        if(this.parent != null)
        {
            this.parent.print();
        }

        System.out.print(" "+this.current);
    }


}

This removes the array but uses Objects to store the Prime (each Sieve holds one prime)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!