这是我的代码:
public class LargestPrimeFactor {
/**
* @param args the command line arguments
*/
public static boolean isPrime(long x){
for (int y=2; y<x; y++){
if (x%y==0){
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Find out the largest prime factor of 600851475143");
long num=600851475143L;
int largest=0;
int y=0;
for (int x=2; x<num; x++){
if (num%x==0&&isPrime(x)==true){
System.out.println(x);
}
}
System.out.println(largest);
}
这是输出:
Find out the largest prime factor of 600851475143
71
839
1471
6857
-716151937
-408464633
-87625999
-10086647
-5753023
-1234169
-486847
-104441
-59569
-6857
-1471
-839
-71
-1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at largestprimefactor.LargestPrimeFactor.main(LargestPrimeFactor.java:32)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 minutes 10 seconds)
如何打印出最大的数字?为什么当&#34; x&#34;时输出显示负数。应该是不断增加,永不减少?
这是我编辑的代码:
public static boolean isPrime(long x){
for (int y=2; y<x; y++){
if (x%y==0){
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Find out the largest prime factor of 600851475143");
long num=600851475143L;
long largest=0;
int y=0;
for (long x=2; x<num/2; x++){
if (num%x==0&&isPrime(x)==true){
System.out.println(x);
if (largest<x){
largest=x;
}
}
}
System.out.println(largest);
}
这是新输出
Find out the largest prime factor of 600851475143
71
839
1471
6857
0
BUILD SUCCESSFUL (total time: 318 minutes 31 seconds)
如何将最终答案打印出来&#34; 6857&#34;而不是&#34; 0&#34;?此外,如果您注意到,该程序的运行时间有点超过5小时。我如何加快这个过程?
答案 0 :(得分:1)
您正在使用int
for
循环,它正在溢出。
使用long变量进行迭代。
for (int x=2; x<num; x++){
^^^
负值的原因是它正在环绕。如果你想找到最大的,你可以使用一个新的long
变量来存储到目前为止最大值。另一种方法是简单地遍历范围反向。
此外,您可以缩短循环,直到检查给定数字的平方根。如果找到一个因子,可以(num / ans)
找到更大的因子。
答案 1 :(得分:0)
您可以通过一些技巧显着加快这一过程:
(x % factor == 0L)
检查,这比isPrime(factor)
检查要快得多。 以下代码结合了这些想法,并在大约十分之一秒内找到答案:
public final class Euler3 {
// Modified from https://optimi.wordpress.com/2010/12/02/how-to-compute-64-bit-integer-square-roots-very-quickly/
public static final long floorSqrt(final long x) {
if (x < 0L) throw new IllegalArgumentException("Cannot take the square root of a negative number");
if ((x & 0xfff0000000000000L) == 0L) return (long) StrictMath.sqrt(x);
final long result = (long) StrictMath.sqrt(2.0d*(x >>> 1));
return result*result - x > 0L ? result - 1L : result;
}
public static final long biggestPrimeFactor(long x) {
// Properly handle zero.
if (x == 0L) return 0L;
// Properly handle negative numbers.
if (x < 0L) x = -x;
long lastPrimeRemoved = 1L;
long sqrtX = floorSqrt(x);
// Handle the prime factor 2.
// (x & 1L) == 0L is true whenever the number is even.
// x >>>= 1 replaces x with x divided by 2 if x is positive.
// >>>= is used because the minimum long can't be negated above.
if ((x & 1L) == 0L) {
x >>>= 1;
while ((x & 1L) == 0L) x >>>= 1;
lastPrimeRemoved = 2L;
sqrtX = floorSqrt(x);
}
// Handle the odd prime factors.
for (long factor = 3L; (x != 1L) && (sqrtX >= factor); factor += 2L) {
if (x % factor == 0L) {
x /= factor;
while (x % factor == 0L) x /= factor;
lastPrimeRemoved = factor;
sqrtX = floorSqrt(x);
}
}
// If we removed all the prime factors, return the last one we removed.
if (x == 1L) return lastPrimeRemoved;
// Otherwise, whatever remains is itself a large prime. Return that.
else return x;
}
public static final void main(final String[] args) {
System.out.println(biggestPrimeFactor(600851475143L));
}
}
答案 2 :(得分:0)
一种可能的解决方案是使用递归,如下所示:
public class PrimeFactor{
public static void main(String[] args){
long n = 600851475143L;
System.out.println("LARGEST = "+largestPrime(2,n));
}
public static long largestPrime(long f, long val){
if (val == f){
return f;
}
else if (val % f ==0)
{
return largestPrime(f, val/f);
}
else
{
return largestPrime(f+1, val);
}
}
}