没有阵列的Eratosthenes筛子?

时间:2014-10-24 09:01:12

标签: java algorithm language-agnostic primes sieve-of-eratosthenes

我必须为eratosthenes' s筛选一个java代码。算法在控制台上打印出一个给定最大值的素数,但我不允许使用数组。我们的教授告诉我们,只有借助循环才能做到。

所以我想了很多,并且搜索了很多关于这个主题的内容并且无法找到答案。我认为它根本不可能,因为你已经存储了已经在某个地方划掉过数字的信息。

我的代码到现在为止:

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

    System.out.print("Primes from 1 to "+n+": 2, ");
    for (int i = 2; i <= n; i++) {
        if(i % mark != 0){
            System.out.print(i+", ");
            mark = i;
        }
    }
}

- &GT;所以,我不允许做#%; i%标记!= 0&#34;命令的数字是我已经打印过的数字的倍数,但如果我没有可以删除索引上的数字的数组,我该怎么做呢?

但是如果有解决方案我会很高兴有人可以与我分享! :)

解决方案可以使用其他编程语言,如果可能,我可以将其自己翻译成java。

提前感谢您和最好的问候


更新:非常感谢大家,非常感谢您的帮助,但我认为不能用基本结构来完成。我所看到的所有使用基本结构打印出素数的算法都不是eratosthenes的筛子。 :(

2 个答案:

答案 0 :(得分:1)

Sieve是关于记住你已经找到的素数。据我所知,没有数组或列表,只有循环,没有办法做到这一点。 我在RosettaCode随机检查了一些例子,没有找到没有数组但只有循环的例子。

如果您将Classes和Methods添加为选项,则可以提出递归设计:

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);
    }


}

这会删除数组但使用Objects存储Prime(每个Sieve保存一个素数)

答案 1 :(得分:0)

我正在收回我刚才所说的内容。在Haskell中,它是没有数组的“筛子”:

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

这是一个健忘的筛子,它非常非常低效。仅使用加法和整数比较。其中的列表推导可以用命令式语言重新编码为循环。或者换句话说,它moves就像筛子一样,但没有标记任何东西,因此不使用数组。

当然,您是否认为它是“真正的”筛子取决于您对筛子的定义。这个人不断地重新创造并放弃它们。或者你可以说它重新实现了 rem 功能。实际上,这也是同样的事情,并且在重用 - 通常通过数组 - 变得可能时,为什么筛子突然变得如此有效的本质。