【问题标题】:Project Euler #7 OptimizationProject Euler #7 优化
【发布时间】:2015-08-29 05:49:50
【问题描述】:

我一直注意到一个带有一些 Project Euler 问题的主题。他们需要大量的时间来完成。 (像最大回文和第 10,001 个素数这样的问题)我希望有一些方法可以优化代码以使其更好。我让这个运行了超过 24 分钟,但没有完成。

public class Seven
{
    public static void main(String[] args)
    {
        //Declare Variables
        int primeCount = 0;
        int numCount = 1;
        int latestPrime = 0;

        while(primeCount <= 10001)
        {
            if(isPrime(numCount))
            {
                primeCount++;
                latestPrime = numCount;
            }
            numCount++;
        }

        System.out.println("The 10,001st prime is: " + latestPrime);
    }

    //This method will determine if a number is prime
    public static boolean isPrime(long num)
    {
        //Check for even number
        if(num % 2 == 0)
            return false;

        //Check for non-prime odd numbers
        for(long i = 3; i <= num; i += 2)
        {
            if(num % i == 0)
                return false;
        }

    //Return that the number is prime
        return true;
}

}

【问题讨论】:

标签: java optimization


【解决方案1】:

你做了很多重复,你不需要在 for 循环中遍历整个数字,只需要直到平方根。

这会在一秒钟内运行。

 // Check for non-prime odd numbers
      for (long i = 3; i <= Math.sqrt(num) +1; i += 2) {
         if (num % i == 0)
            return false;
      }

如果您想进一步优化,您可以将质数存储在一个数组中,并且只检查该数字是否可以被之前的质数整除。

【讨论】:

  • 我无法相信它的速度有多快。谢谢你的建议!我一定会把它记在脑后,以备将来的节目使用!
【解决方案2】:

这个程序打印 10001 个第一个素数。正如@Tejash Desai 建议的那样,可以进行 2 项优化:

(1) 将找到的素数保存在一个列表中,这样新素数的测试只需要在这个列表中的项目上进行,而不是所有奇数;和

(2) 只测试一个数的平方根以下的因子。

void printPrimes() {
    // Find first 10001 primes
    int p = 0;
    for (var i = 2; i <= 10001; i++) {
        p = nextPrime();
        Console.WriteLine("Prime #{0}: {1}", i, p);
    }
}

// Set of known primes
List<int> primes = new List<int>() {2};

// Find the prime next to the last one that was found
int nextPrime() {
    int k = primes[primes.Count - 1] + 1;
    while (!testPrimeUsingKnownSetOfPrimes(k)) {
        k = k + 1;
    }

    primes.Add(k);
    return k;
}

// Check if a number is prime, using the set of known primes
bool testPrimeUsingKnownSetOfPrimes(int n) {

    foreach (var p in primes) {
        // Largest prime factor of a number can't be greater than square root of the number
        if (p > Math.Sqrt(n)) {
            return true;
        }

        if (n % p == 0) {
            return false;
        }
    }

    return true;
}

PS用 C# 编写。

【讨论】:

    【解决方案3】:

    循环直到小于或等于 n 的平方根

    //Check for non-prime odd numbers for(long i = 3; i <= Math.sqrt(num); i += 2) { if(num % i == 0) return false; } 
    

    另外,另一个优化是继续将您迄今为止遇到的所有素数存储在一个 ArrayList 中,然后只遍历该列表中的循环。

    //Check for non-prime odd numbers for(int i = 0; i <= arrayList.size(); i ++) { if(num % arrayList.get(i) == 0) return false; }             arrayList.add(num);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      相关资源
      最近更新 更多