减少 Java 程序的执行时间
Decrease execution time of the Java program
我为项目 Euler 的第二个问题编写了以下程序,用于问题:"Project Euler #3: Largest prime factor"。它应该打印出所提供输入的所有最高质因数。
import java.util.Scanner;
public class euler_2 {
public static boolean isPrime(int n) {
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
for (int i = 0; i < a; i++) {
int b = sc.nextInt();
for (int j = b; j >= 1; j--) {
boolean aa = isPrime(j);
if (aa == true && b % j == 0) {
b = j;
break;
}
}
System.out.println(b);
}
}
}
我可以对程序进行哪些更改以使其执行速度更快?对于这个问题,更好的算法是什么?
尝试将数字分解为 2 个因数。重复目前找到的最大因子,直到找到一个无法因式分解的因子 - 即最大素因子。
您可能会尝试通过多种不同的方法对数字进行因式分解,但由于它们只是整数,因此费马法甚至试除法(从 sqrt(N) 开始)可能都可以。参见 http://mathworld.wolfram.com/FermatsFactorizationMethod.html
你的方法的问题在于,对于每个数字 N
,你尝试每个小于或等于 N
的数字是否是质数,然后再尝试它是否是 [= 的约数11=]。
明显的改进是先检查它是否是除数,然后再检查它是否是素数。但很可能这不会有太大帮助。
您可以做的只是开始检查每个数字是否是数字的约数。如果是除数,则将其除。你继续这个直到 sqrt(N)
。
我已经很长时间没有用 java 做过任何事情了,但这是 Go 实现,很可能任何 Java 人都可以转换为 Java。
func biggestPrime(n uint64) uint64 {
p, i := uint64(1), uint64(0)
for i = 2; i < uint64(math.Sqrt(float64(n))) + uint64(1); i++ {
for n % i == 0 {
n /= i
p = i
}
}
if n > 1 {
p = n
}
return p
}
使用我的算法,您需要 O(sqrt(N)) 才能找到一个数的最大素数。在你的情况下是 O(N * sqrt(N))
我为项目 Euler 的第二个问题编写了以下程序,用于问题:"Project Euler #3: Largest prime factor"。它应该打印出所提供输入的所有最高质因数。
import java.util.Scanner;
public class euler_2 {
public static boolean isPrime(int n) {
if (n % 2 == 0) return false;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0)
return false;
}
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
for (int i = 0; i < a; i++) {
int b = sc.nextInt();
for (int j = b; j >= 1; j--) {
boolean aa = isPrime(j);
if (aa == true && b % j == 0) {
b = j;
break;
}
}
System.out.println(b);
}
}
}
我可以对程序进行哪些更改以使其执行速度更快?对于这个问题,更好的算法是什么?
尝试将数字分解为 2 个因数。重复目前找到的最大因子,直到找到一个无法因式分解的因子 - 即最大素因子。
您可能会尝试通过多种不同的方法对数字进行因式分解,但由于它们只是整数,因此费马法甚至试除法(从 sqrt(N) 开始)可能都可以。参见 http://mathworld.wolfram.com/FermatsFactorizationMethod.html
你的方法的问题在于,对于每个数字 N
,你尝试每个小于或等于 N
的数字是否是质数,然后再尝试它是否是 [= 的约数11=]。
明显的改进是先检查它是否是除数,然后再检查它是否是素数。但很可能这不会有太大帮助。
您可以做的只是开始检查每个数字是否是数字的约数。如果是除数,则将其除。你继续这个直到 sqrt(N)
。
我已经很长时间没有用 java 做过任何事情了,但这是 Go 实现,很可能任何 Java 人都可以转换为 Java。
func biggestPrime(n uint64) uint64 {
p, i := uint64(1), uint64(0)
for i = 2; i < uint64(math.Sqrt(float64(n))) + uint64(1); i++ {
for n % i == 0 {
n /= i
p = i
}
}
if n > 1 {
p = n
}
return p
}
使用我的算法,您需要 O(sqrt(N)) 才能找到一个数的最大素数。在你的情况下是 O(N * sqrt(N))