[英]Find the largest prime factor of a given number
我正在编写这个方法,它应该返回给定数字的最大素数。 它工作正常,直到输入 45 并且 output 为 15,即使 output 应该是 5。我正在努力寻找错误。 请帮忙。
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;
}
您需要添加一个标志来检查值i
的可分性。 只有当i
是素数时,它才会保持正确。 稍后如果标志仍然为真,您可以返回i
否则您需要继续迭代
您的代码中发生的情况是,当 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;
}
}
简而言之:“主要”验证是错误的。
在您的代码中,在内部循环中,您希望所有数字都是“i”的因子,这当然是错误的。
您的代码将检索您输入的最大因子,其中有一个数字不是它的因子(i % j,= 0)。 因此它的最大因素(不管素数)。
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);
}
}
我想出了这个。 如果您从 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;
}
}
它在达到 45 之前无法正常工作。它在 4、8、12、16、18、20、24、27、28、30、32、36、40、42 和 44 失败。它返回 -1每个素数,这是正确的,但它也为 4 返回 -1。它通常会找到最大的因子,不管它是否是素数。
您的外部循环查找因子,从最大的开始。 你的内循环没有意义。 它需要对素数进行测试。 看起来你的意思是当它找到 i 的一个因素时它会退出,但它并没有这样做。 相反,当它发现一个不是一个因素的数字时,它就会退出。 continue 语句告诉它到 go 到 j 的下一个值。 您可能打算将 go 指向 i 的下一个值。 为此,您可以使用 break。 那将摆脱内部循环。 或者您可以 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;
这让你更接近,但它仍然失败为 2 的幂,以及它找到 p ^ n 的情况,其中 p 是一个素数。
此外,以数字 1 开始外循环是没有意义的。 您可以跳过所有高于 number/2 的数字。 它们都不会产生模零。
我建议做这样的事情。 首先,考虑2*2*3*47 = 564
。 564 is <= 24
。 所以你需要做的就是除以最多24
的数字。 首先,消除2
。 剩下3*47
。 接下来是3
,它留下47
。 由于从4 thru 24
中没有其他数字可以除以47
,因此47
必须是素数。 如果它是复合的,它的主要因素将被早期的除数之一分解。
这可以通过在单独的循环中分解出2
来进一步优化。 然后从3
开始,只除以奇数(如果有的话, 2
已经消除了偶数)。
如果在数字减少到 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));
}
印刷
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
方法
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;
}
此代码将帮助您找到最大的素数。 大多数在线服务器不允许它运行。 只需更改 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.