Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个程序的Java复杂性类?_Java_Queue_Big O_Primes_Sieve Of Eratosthenes - Fatal编程技术网

这个程序的Java复杂性类?

这个程序的Java复杂性类?,java,queue,big-o,primes,sieve-of-eratosthenes,Java,Queue,Big O,Primes,Sieve Of Eratosthenes,对于这个赋值,我必须创建一个程序,该程序使用Eratosthenes筛查找并返回一个包含整数n以下的所有素数的队列。当我让它工作时,我仍然在思考代码的大O。似乎我在其中嵌套了太多的循环,使得它在计算非常大的数字时运行得太慢。例如,计算: Queue<Integer> q = PrimeQueue.getPrimes(1234567); 快三分钟了!我想问的是:像这样的任务是否需要如此长的运行时间?在这个任务的范围内,是否有一种更为流程友好的方法来实现这一点,同时仍然使用两个队列并返

对于这个赋值,我必须创建一个程序,该程序使用Eratosthenes筛查找并返回一个包含整数n以下的所有素数的队列。当我让它工作时,我仍然在思考代码的大O。似乎我在其中嵌套了太多的循环,使得它在计算非常大的数字时运行得太慢。例如,计算:

Queue<Integer> q = PrimeQueue.getPrimes(1234567);
快三分钟了!我想问的是:像这样的任务是否需要如此长的运行时间?在这个任务的范围内,是否有一种更为流程友好的方法来实现这一点,同时仍然使用两个队列并返回其中一个队列?这个程序的复杂度等级是多少?谢谢

这是我的密码:

public static Queue<Integer> getPrimes(int n) {
    if (n < 2) { // If illegal argument
        throw new IllegalArgumentException("n can't be less than 2.");
    }
    Queue<Integer> numbers = new LinkedList<Integer>();
    Queue<Integer> primes = new LinkedList<Integer>();

    // fills queue w/ numbers from 2 to n inclusive // throw exception if n < 2
    for (int i = 2; i <= n; i++) {
        numbers.add(i);
    }

    do { // do while b/c it will always execute once
        int prime = numbers.remove(); // gets first prime number from first value of numbers
        primes.add(prime); // adds to the prime 
        int numbersSize = numbers.size(); // used to keep track when looping over the numbers queue
        for (int i = 0; i < numbersSize; i++) { // goes through each number to elim multiples of prime
            int numTemp = numbers.remove(); // will add to back of numbers if not divisible by prime (otherwise deleted)
            if (numTemp % prime != 0) {
                numbers.add(numTemp); // put back into back of queue
            }
        }
    } while (!numbers.isEmpty()); // Keeps running as long as there is a value in numbers
    return primes;
}

我怀疑你删除了所有的复合数字,并且每次都重新添加它们,这一事实导致了严重的减速。您在^2上有效地迭代了numbers队列,可能更接近于On*logn,我想,并重复分配和释放队列元素。那是很多浪费的循环

我的建议是您使用了错误的数据结构。您需要具有随机或关联访问权限的内容。我的建议是,要么分配一个布尔数组并标记每个过程中已知的所有数字,要么使用一个集合,该集合允许接近恒定的时间访问,并在结束时加快迭代,但代价是每次过程的删除速度变慢

编辑:正如Will Ness指出的,另一个主要问题是,当您只需要迭代到sqrtn时,您正在从2迭代到n。我错过了一个字符细节,因为我被其他设计问题缠住了,这是我的错误。

像这样的任务需要这么长的运行时间吗?没有

在分配的范围内,是否有一种更为流程友好的方法,使用两个队列并返回其中一个队列?是的,这就是方法

您可以更早地停止,从而使代码运行得更快:

int numTemp = 0;
int prime = 0;
do { 
    prime = numbers.remove(); 
    numTemp = prime;  // in case numbers are now empty
    primes.add(prime); 
    int numbersSize = numbers.size(); 
    for (int i = 0; i < numbersSize; i++) { 
        numTemp = numbers.remove(); 
        if (numTemp % prime != 0) {
            numbers.add(numTemp); 
        }
    }
} while (prime*prime < numTemp); // numTemp is the last number in numbers

// now all numbers left in 'numbers' are prime!!
.... ;  // add them into your 'primes' queue, and then
return primes;

提前停止是可以的,因为如果n==ab和a,我知道使用队列非常有限,但我只限于使用两个队列,一个用于存储2到n的整数,另一个用于存储并返回2到n的所有素数。如果需要使用队列,考虑存储包含整数和已知复合变量的不同对象类型,不要重复删除和插入项。这也应该有助于你的表现。我不认为它太宽泛——这三个问题非常具体。