[英]Project Euler Number 3: Largest prime factor
Here is my code: 这是我的代码:
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);
}
Here is the output: 这是输出:
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)
How do I print out the largest number? 如何打印出最大的数字? and why does the output show negative numbers when "x" is supposed to be constantly increasing, never decreasing? 当“ x”应该不断增加而不是减少时,为什么输出显示负数?
Here is my edited code: 这是我编辑的代码:
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);
}
Here is the new output 这是新的输出
Find out the largest prime factor of 600851475143
71
839
1471
6857
0
BUILD SUCCESSFUL (total time: 318 minutes 31 seconds)
How do I get the final answer to be printed out as "6857" rather than "0"? 如何获得最终答案以“ 6857”而不是“ 0”的形式打印出来? Also, if you notice, the run time for the program was a little over 5 hours. 另外,如果您注意到,该程序的运行时间将超过5个小时。 How do I speed up this process? 如何加快此过程?
You are using an int
for the for
loop, which is overflowing. 您正在for
循环中使用int
,该循环正在溢出。 Use a long variable to iterate. 使用长变量进行迭代。
for (int x=2; x<num; x++){
^^^
The reason for the negative values is that it is wrapping around. 负值的原因是它回绕。 If you want to find just the largest, you could use a new long
variable to store the max-seen so far. 如果您只想找到最大的,则可以使用新的long
变量来存储到目前为止的最大可见数。 Another way is to simply iterate over the range in reverse . 另一种方法是简单地反向迭代范围。
Additionally, you can shorten your loop to just check till the square root of the given number. 此外,您可以缩短循环,仅检查直到给定数字的平方根即可。 If you find a factor, you can do (num / ans)
to find the larger factor. 如果找到一个因数,则可以执行(num / ans)
查找较大的因数。
You can speed up the process significantly with a few tricks: 您可以通过以下一些技巧大大加快该过程:
(x % factor == 0L)
check, which is a much, much faster check than isPrime(factor)
. 如果它们不是素数,则它们自己的素因数将已经从数量中除掉,因此潜在因数将很快无法通过(x % factor == 0L)
检查,这比isPrime(factor)
。 The following code combines these ideas and finds the answer in about a tenth of a second: 以下代码结合了这些想法,并在大约十分之一秒的时间内找到了答案:
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));
}
}
A possible solution is to use recursion as shown below: 一种可能的解决方案是使用如下所示的递归:
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);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.