简体   繁体   English

找到给定数字的最大素数

[英]Find the largest prime factor of a given number

I am writing this method which should return the largest prime factor of a given number.我正在编写这个方法,它应该返回给定数字的最大素数。 It was working fine till 45 was entered and the output was 15, even though the output should be 5. I am struggling to find the bug.它工作正常,直到输入 45 并且 output 为 15,即使 output 应该是 5。我正在努力寻找错误。 Please help.请帮忙。

public static int getLargestPrime(int number) {

        if (number < 0) {
            return -1;
        }

        for (int i = number-1; i > 1; i--) {
            if (number % i == 0) {
                for (int j = 2; j < i; j++) {
                    if (i % j == 0) {
                        continue;
                    }
                    return i;
                }
            }
        }
        return -1;

    }

You need to add a flag to check the divisibility of the value i .您需要添加一个标志来检查值i的可分性。 It will remain true only if i is a prime number.只有当i是素数时,它才会保持正确。 Later if the flag remains true, you can return i else you need to continue iterating稍后如果标志仍然为真,您可以返回i否则您需要继续迭代

What's happening in your code is that when i=15, and the inner loop starts iterating starting from 2, 15%2!=0 so it skips the if condition and returns 15您的代码中发生的情况是,当 i=15 时,内部循环从 2 开始迭代,15%2!=0 所以它跳过了 if 条件并返回 15

for (int i = number-1; i > 1; i--) {
        if (number % i == 0) {
            bool flag = true;
            for (int j = 2; j < i; j++) {
                if (i % j == 0) {
                    flag = false;
                    break;
                }
            }
            if(flag)
                return i;
        }
    }

In short: The "prime" validation is wrong.简而言之:“主要”验证是错误的。

In your code, in the inner loop, you expect all numbers will be factors of "i", which is of course wrong.在您的代码中,在内部循环中,您希望所有数字都是“i”的因子,这当然是错误的。

Your code will retrieve the largest factor of your input, which there is a number which is not a factor of it (i % j,= 0).您的代码将检索您输入的最大因子,其中有一个数字不是它的因子(i % j,= 0)。 therefore the largest factor of it (regardless of primality).因此它的最大因素(不管素数)。

  1. Find the prime numbers before the input number查找输入数之前的素数
  2. Sort the prime numbers in reverse order以相反的顺序对质数进行排序
  3. Iterate over the prime numbers and check whether its an exact multiple遍历素数并检查它是否是精确的倍数
  4. If its an exact multiple return the prime number如果它是一个精确的倍数,则返回素数
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

class PrimeFactorTest {

    public static void main(String[] args) throws Exception {
        int[] inputs = new int[]{-100, -25, -2, -1, 0, 1, 2, 3, 4, 5, 100, 1223, 2000, 874032849,
            Integer.MAX_VALUE, Integer.MAX_VALUE};

        for (final int input : inputs) {
            Optional primeFactor = largestPrimeFactor(input);
            if (primeFactor.isPresent()) {
                System.out.println("Largest Prime Factor of " + input + " is " + primeFactor.get());
            } else {
                System.out.println("No Prime Factor for " + input);
            }
        }
    }

    public static Optional<Integer> largestPrimeFactor(final int input) {
        if (input < 0) {
            return largestPrimeFactor(Math.abs(input));
        }
        final int sqrt = (int) Math.sqrt(input);
        List<Integer> primes = getPrimesInDescendingOrder(sqrt);
        if (primes.size() == 0) {
            return Optional.empty();
        }
        for (final int prime : primes) {
            if (input % prime == 0) {
                return Optional.of(prime);
            }
        }
        return Optional.of(input);
    }

    private static List<Integer> getPrimesInDescendingOrder(final int input) {
        if (input < 2) {
            return new ArrayList<>();
        }
        List<Integer> primes = new ArrayList<>();
        primes.add(2);
        for (int current = 3; current <= input; current++) {
            boolean isPrime = true;
            for (int prime : primes) {
                if (current % prime == 0) {
                    isPrime = false;
                }
            }
            if (isPrime) {
                primes.add(current);
            }
        }
        primes.sort(Collections.reverseOrder());
        return Collections.unmodifiableList(primes);
    }
}

I came up with this.我想出了这个。 If you start at 2 and work up the way, you are eliminating all the non-primes before you hit them, as they will no-longer be factors of the remainder.如果您从 2 开始并逐步向上,您将在击中它们之前消除所有非质数,因为它们将不再是余数的因数。

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class LargestPrimeFactor {
    @Test
    public void testGetLargestPrime() {
        assertEquals(2, getLargestPrime(2));
        assertEquals(3, getLargestPrime(3));
        assertEquals(2, getLargestPrime(4));
        assertEquals(5, getLargestPrime(5));
        assertEquals(3, getLargestPrime(6));
        assertEquals(7, getLargestPrime(7));
        assertEquals(2, getLargestPrime(8));
        assertEquals(3, getLargestPrime(9));
        
        assertEquals(23, getLargestPrime(23*23*7*2*5*11*11));
    }

    int getLargestPrime(int number) {
        for (int i = 2; number > i; i++) {
            while (number > i && number % i == 0) {
                number = number / i;
            }
        }
        return number;
    }
}

It wasn't working fine until it reached 45. It failed for 4, 8, 12, 16, 18, 20, 24, 27, 28, 30, 32, 36, 40, 42, and 44. It returned -1 for every prime number, which is correct, but it also returned -1 for 4. It usually finds the largest factor, regardless of whether it's prime.它在达到 45 之前无法正常工作。它在 4、8、12、16、18、20、24、27、28、30、32、36、40、42 和 44 失败。它返回 -1每个素数,这是正确的,但它也为 4 返回 -1。它通常会找到最大的因子,不管它是否是素数。

Your outer loop finds factors, starting with the largest.您的外部循环查找因子,从最大的开始。 Your inner loop doesn't make sense.你的内循环没有意义。 It needs to have a test for primality.它需要对素数进行测试。 It looks like you meant it to quit when it finds a factor of i, but it doesn't do that.看起来你的意思是当它找到 i 的一个因素时它会退出,但它并没有这样做。 Instead, it quits when it finds a number that isn't a factor.相反,当它发现一个不是一个因素的数字时,它就会退出。 The continue statement tells it to go to the next value of j. continue 语句告诉它到 go 到 j 的下一个值。 You probably meant for it to go on to the next value of i.您可能打算将 go 指向 i 的下一个值。 To do that, you could use break.为此,您可以使用 break。 That would bail out of the inner loop.那将摆脱内部循环。 Or you could label the outer loop and use the label in the continue statement, which is probably what you had in mind:或者您可以 label 外循环并在 continue 语句中使用 label ,这可能是您的想法:

candidates:
for (int i = number - 1; i > 1; i--) {
  if (number % i == 0) {
    for (int j = 2; j < i; j++) {
      if (i % j == 0) {
        continue candidates; // This continues the outer loop
      }
      return i;
    }
  }
}
return -1;

That gets you closer, but it still fails for powers of two, and for cases where it finds p^n where p is a prime number.这让你更接近,但它仍然失败为 2 的幂,以及它找到 p ^ n 的情况,其中 p 是一个素数。

Also, there's no point in starting the outer loop with number-1.此外,以数字 1 开始外循环是没有意义的。 You can skip all the numbers higher than number/2.您可以跳过所有高于 number/2 的数字。 None of them will produce a modulo of zero.它们都不会产生模零。

I would recommend doing something like this.我建议做这样的事情。 First, consider 2*2*3*47 = 564 .首先,考虑2*2*3*47 = 564 The square root of 564 is <= 24 . 564 is <= 24 So all you need to do is divide by numbers up to 24 .所以你需要做的就是除以最多24的数字。 First, eliminate 2 .首先,消除2 That leaves 3*47 .剩下3*47 Next is 3 which leaves 47 .接下来是3 ,它留下47 Since no other number from 4 thru 24 divides 47 , 47 must be a prime.由于从4 thru 24中没有其他数字可以除以47 ,因此47必须是素数。 If it were composite, it's prime factors would have been factored out by one of the earlier divisors.如果它是复合的,它的主要因素将被早期的除数之一分解。

This can be further optimized by factoring out 2 in a separate loop.这可以通过在单独的循环中分解出2来进一步优化。 Then starting with 3 , start dividing by only the odd numbers ( 2 already eliminated the even factors if there were any).然后从3开始,只除以奇数(如果有的话, 2已经消除了偶数)。

If the situation arises when the number is reduced to 1, then the last divisor that did the reduction must be the largest prime.如果在数字减少到 1 时出现这种情况,那么最后一个进行减少的除数必须是最大的素数。

int[] testData = { 2, 10, 2 * 2 * 5, 2 * 3 * 47 * 5,
        2 * 2 * 2 * 3 * 3 * 3 * 17 * 17 * 17 };
for (int v : testData) {
    System.out.printf("%8s - largest prime factor = %s%n", v,
            getLargestPrime(v));
}

Prints印刷

       2 - largest prime factor = 2
      10 - largest prime factor = 5
      20 - largest prime factor = 5
    1410 - largest prime factor = 47
 1061208 - largest prime factor = 17

The method方法

public static int getLargestPrime(int number) {
    // no primes less than 2 exist.
    if (number < 2) {
        return -1;
    }
    while (number % 2 == 0) {
        number /= 2;
    }
    
    int lastDivisor = 2;
    for (int d = 3; d <= Math.sqrt(number); d += 2) {
        lastDivisor = d;
        while (number % d == 0) {
            number /= d;
        }
    }
    
    return number == 1 ? lastDivisor : number;
}

This code will help you find the largest prime number.此代码将帮助您找到最大的素数。 Most online servers won't allow it to run.大多数在线服务器不允许它运行。 Just change the value of n.只需更改 n 的值。

public class PrimeExample{    
         public static void main(String args[]){          
          for(int n = 100;n<=1000;n++){
           int i,m=0,flag=0; 
              m=n/2;      
              if(n==0||n==1){  
               System.out.println(n+" is not prime number");      
              }else{  
               for(i=2;i<=m;i++){      
                if(n%i==0){      
                 System.out.println(n+" is not prime number");      
                 flag=1;      
                 break;      
                }      
               }      
               if(flag==0)  { System.out.println(n+" is prime number"); }  
            }//end of else  
          }
        }    
    }  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM