首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中如何优化算法以确定10位长素数

在java中如何优化算法以确定10位长素数
EN

Stack Overflow用户
提问于 2017-03-29 04:16:41
回答 2查看 247关注 0票数 0

我目前是java和编程的新手,我正在研究一种算法,它可以确定特定给定范围内的质数。目前它工作在六个范围内,数字小于10亿,当我试图确定一个10位数长度的数字时,它失败了。我知道它需要更改为long,因为数字超出了范围,但我不确定如何更改。

这是代码中确定数字是否为质数的部分:

代码语言:javascript
复制
public ArrayList<Integer> getPrimes(int StartPos, int n) {
    ArrayList<Integer> primeList = new ArrayList<>();

    boolean[] primes = new boolean[n + 1];
    for (int i = StartPos; i < primes.length; i++) {
        primes[i] = true;
    }
    int num = 2;
    while (true) {
         for (int i = 2;; i++) {
              int m = num * i;
              if (m > n) {
                    break;
              } else {
                    primes[m] = false;
              }
         }
         boolean nextNum = false;
         for (int i = num + 1; i < n + 1; i++) {
              if (primes[i]) {
                    num = i;
                    nextNum = true;
                    break;
              }
         }
         if (!nextNum) {
              break;
         }
    }
    for (int i = 0; i < primes.length; i++) {
         if (primes[i]) {
            primeList.add(i);           
         }      
    }
    return primeList;  
}

我在网上查看,发现也许我可以使用向量,但我没有使用它们的经验,而且它们比数组相对要慢。

EN

回答 2

Stack Overflow用户

发布于 2017-03-29 04:26:46

你可以试试BigInteger#isProbablePrime:https://www.tutorialspoint.com/java/math/biginteger_isprobableprime.htm

代码语言:javascript
复制
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

// Java 8
public class FindPrimes {
    public static void main(String[] args) {
        System.out.println("1 - 100 primes: " + findPrimes(1L, 99L));
        System.out.println("some 10-digit primes: " + findPrimes(99_999_999_999L, 20000L));
    }

    private static List<Long> findPrimes(long start, long quant) {
        return LongStream.rangeClosed(start, start + quant).filter(v ->
                BigInteger.valueOf(v).isProbablePrime(1)).boxed().collect(Collectors.toList());
    }
}
票数 2
EN

Stack Overflow用户

发布于 2017-03-29 21:16:26

你说你正在学习,所以我将用伪代码给你一个提纲,而不是答案。

一般来说,在一个范围内查找质数的方法是:

代码语言:javascript
复制
repeat
  pick a number in the range
until (the number is prime)

你想要一个十位数字。在避免明显的非质数的情况下生成候选对象的一种方法是:

代码语言:javascript
复制
start with digit in [1..9]  // No leading zero.
repeat 8 times
  append a digit in [0..9]
endrepeat
append a digit in [1, 3, 7, 9]  // Final digits for large primes.

这会给你一个十位数的可能素数。

现在你需要测试来检查它是质数。

有像Miller-Rabin这样的测试,你可以尝试一下,但如果你是真正的初学者,可能就不会了。我建议设置一个Eratosthenes筛子,覆盖数字到10,000,这是您的上限10,000,000,000的平方根。这将使您快速访问您的数字的平方根以下的所有质数。仅在程序开始时设置筛子一次。使其成为一个单独的类,并包含一个int nextPrime(int n)方法,该方法在所提供的参数之后返回下一个质数。一旦准备就绪,您就可以编写一个试除法来测试您的十位数:

代码语言:javascript
复制
boolean method isPrime(tenDigitNumber)
  testPrime <- 2
  limit <- square root of tenDigitNumber  // Only calculate this once.
  while (testPrime < limit)
    if (tenDigitNumber MOD testPrime == 0)
      return false  // Number is not prime.
    else
      testPrime <- sieve.nextPrime(testPrime)
    endif
  endwhile
  return true  // If we get here then the number is prime.
end isPrime

因为您已经提前设置了筛子,所以它应该运行得相当快。如果它太慢,那么是时候考虑编码Miller-Rabin或其他重载主要测试方法之一了。

除了Eratosthenes类的筛子之外,另一个有用的实用方法是返回整数平方根的iSqrt()方法。我自己的版本使用了牛顿-拉夫森方法,尽管毫无疑问还有其他可能性。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43079130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档