简体   繁体   English

Java中数字的最大素数

[英]Largest prime factor of a number in Java

I am trying to find the Largest prime factor of a number while solving this problem here . 在这里解决此问题时,我试图找到一个数的最大素数。 I think that I am doing everything right, however one of the test case (#2) is failing and I can't think of any corner case where it might fail. 我认为我所做的一切都正确,但是其中一个测试用例(#2)失败了,我想不出任何可能失败的极端情况。 Here's my code, please have a look and try to spot something. 这是我的代码,请看一下并尝试发现一些东西。

public class ProblemThree
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();
        for (int i = 0; i < T; i++)
        {
            System.out.println(largestPrime(scanner.nextLong()));
        }
    }

    private static long largestPrime(long n)
    {
        while (n % 2 == 0)
        {
            n = n / 2;  // remove all the multiples of 2
        }
        while (n % 3 == 0)
        {
            n = n / 3; // remove all the multiples of 2
        }

        // remove multiples of prime numbers other than 2 and 3
        while (n >= 5)
        {
            boolean isDivisionComplete = true;
            for (long i = 5; i < Math.ceil(Math.sqrt(n)); i++)
            {
                if (n % i == 0)
                {
                    n = n / i;
                    isDivisionComplete = false;
                    break;
                }
            }
            if (isDivisionComplete)
            {
                break;
            }
        }
        return n;
    }
}

Basically, what I am doing is: 基本上,我正在做的是:

Largest_Prime(n):
1. Repeatedly divide the no by any small number, say x where 0 < x < sqrt(n).
2. Then set n = n/x and repeat steps 1 and 2 until there is no such x that divides n.
3  Return n.

似乎您的代码中有一些错误,例如当您输入16 maximumPrime函数返回1时。对于输入为3的幂的情况,这是正确的。

Detailed Algorithm description: You can do this by keeping three variables: The number you are trying to factor (A) A current divisor store (B) A largest divisor store (C) Initially, let (A) be the number you are interested in - in this case, it is 600851475143. Then let (B) be 2. Have a conditional that checks if (A) is divisible by (B). 详细的算法描述:可以通过保留三个变量来做到这一点:尝试分解的数字(A)当前除数的存储(B)最大除数的存储(C)最初,让(A)为您感兴趣的数字-在这种情况下为600851475143。然后令(B)为2。有一个条件检查(A)是否可被(B)整除。 If it is divisible, divide (A) by (B), reset (B) to 2, and go back to checking if (A) is divisible by (B). 如果可以将其整除,则将(A)除以(B),将(B)重置为2,然后返回检查(A)是否可以被(B)整除。 Else, if (A) is not divisible by (B), increment (B) by +1 and then check if (A) is divisible by (B). 否则,如果(A)无法被(B)整除,则将(B)加+1,然后检查(A)是否可被(B)整除。 Run the loop until (A) is 1. The (3) you return will be the largest prime divisor of 600851475143. 运行循环,直到(A)为1。您返回的(3)将是600851475143的最大除数。

 public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int t = in.nextInt();
    for(int a0 = 0; a0 < t; a0++){
        long n = in.nextLong();
        long A=n;
        long B=2;
        long C=0;
        while(Math.pow(B,2)<=A)
            {
            if(A%B==0)
                {
                C=B;
                A=A/B;
                B=2;
            }
            else
               B++;

        }
           if(A>=C)
            C=A;
           if(A==1)
               { C=2;
                break;
               }
         System.out.println(C);   
    }
}

Why are you removing multiples of 2 and multiples of 3? 为什么要删除2的倍数和3的倍数? This way if you have a number that is any combination of powers of 2 and 3 you will get your answer as 1 which is clearly wrong. 这样,如果您的数字是2和3的幂的任意组合,您将得到答案为1,这显然是错误的。

For this problem you can do the naive way of looping from 2 to sqrt(n) and store the largest number which divides n, when you finish your loop just return the highest divisor you found. 对于此问题,您可以执行从2到sqrt(n)循环的幼稚方法,并存储除以n的最大数,当您完成循环时,只需返回找到的最高除数。

1 drop your loop for 2 and 3. If not, you dont get 2, 2x2, 3, 2x3, ... all multiples of 2 and 3 1放弃2和3的循环。否则,您不会得到2、2x2、3、2x3,...的所有2和3的倍数

2 change your loop to stop at 2 (and not 5): 2更改循环以在2(而不是5)处停止:

while (n >= 2)
{

3 stop if 2 如果2停3

if (n==2) return 2;

4 loop from 2 2的4个循环

and

5 loop until sqrt(n), with <= and not only < (if not, you dont get prime X Prime) 5循环直到sqrt(n),使用<=且不仅<(如果不是,则不会得到素数X Prime)

for (long i = 2; i <= Math.ceil(Math.sqrt(n)); i++)

One easy way of extracting prime factors is like this: 提取主要因子的一种简单方法是这样的:

/**
 * Prime factors of the number - not the most efficient but it works.
 *
 * @param n - The number to factorise.
 * @param unique - Want only unique factors.
 * @return - List of all prime factors of n.
 */
public static List<Long> primeFactors(long n, boolean unique) {
  Collection<Long> factors;
  if (unique) {
    factors = new HashSet<>();
  } else {
    factors = new ArrayList<>();
  }
  for (long i = 2; i <= n / i; i++) {
    while (n % i == 0) {
      factors.add(i);
      n /= i;
    }
  }
  if (n > 1) {
    factors.add(n);
  }
  return new ArrayList<>(factors);
}

Those first loops are a problem. 那些第一个循环是个问题。 They will reduce all even numbers to 1 - thus missing 2 as the factor. 他们会将所有偶数减少为1因此缺少2作为因子。 Changing your code to use: 更改代码以使用:

while (n > 2 && n % 2 == 0) {
  n = n / 2;  // remove all the multiples of 2
}
while (n > 3 && n % 3 == 0) {
  n = n / 3; // remove all the multiples of 2
}

You still have further issues - eg you report the largest prime factor of 25 to be 25 and the largest prime factor of 49 to be 49 . 您还有其他问题-例如,您报告的最大质数2525 ,最大质数4949

Just run this code using yours and mine to see where yours fails: 只需使用您的代码运行我的代码,然后查看我的代码失败的地方:

for (long i = 1; i < 1000; i++) {
  long largestPrime = largestPrime(i);

  List<Long> primeFactors = primeFactors(i, true);
  if (primeFactors.size() > 0) {
    Collections.sort(primeFactors, Collections.reverseOrder());
    long highestFactor = primeFactors.get(0);
    if (largestPrime != highestFactor) {
      System.out.println("Wrong! " + i + " " + largestPrime + " != " + primeFactors);
    }
  } else {
    System.out.println("No factors for " + i);
  }
}

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

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