繁体   English   中英

找到给定数字的最大素数

[英]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)。 因此它的最大因素(不管素数)。

  1. 查找输入数之前的素数
  2. 以相反的顺序对质数进行排序
  3. 遍历素数并检查它是否是精确的倍数
  4. 如果它是一个精确的倍数,则返回素数
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.

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