簡體   English   中英

Java中更快的Erathostenes篩選和素數分解

[英]faster Sieve of Erathostenes and prime number factorization in Java

我的輸入是Integer 達到該值,應找到所有素數並在5列中打印,然后我必須對素數進行“素數分解”並打印結果。

不錯,但是還不太慢...

public class Bsp07 {
  public static void main(String[] args) {

     System.out.println("Enter the upper bound for prime number search");
     int n = SavitchIn.readLineInt();
     int[] aZahlen = new int[n - 1];
     for (int el = 0, zahl = 2; el != n - 1; el++, zahl++)
        aZahlen[el] = zahl;

     int p = 2, altesP; // next unmarked number
     boolean aus = false; // when unmarked elements are "aus" (off)

     while (aus == false) {

     // marks Elements; using For loop since for-each loop doesn't work
        for (int i = 0; i < aZahlen.length; i++) {
           if ((aZahlen[i] % p == 0) && (aZahlen[i] != p))
              aZahlen[i] = 0;
        }

        altesP = p; // merkt sich altes p
     // update p, find next unmarked Element
        for (int el : aZahlen) {
           if ((el != 0) && (el > altesP)) {
              p = el;
              break;
           }
        }
     // if p stayed the same unmarked elements are "aus" (off)
        if (altesP == p)
           aus = true;
     }

     int nervVar = 0;
     for (int pr : aZahlen) {
        if(pr==0) 
           continue;
        System.out.print(pr + " ");
        nervVar++;
        if ((nervVar % 5 == 0)) System.out.print("\n");
     }

     /* Factorization */
     System.out.print("\n" + n + " = ");
     for (int i = 0, f = 0; n != 1; i++, f++) {
        while(aZahlen[i]==0) i++;
     /*
      * If the prime divides: divide by it, print the prime,
      * Counter for further continuous decrease with prime number if n = 1,
      * Stop
      */
        if (n % aZahlen[i] == 0) {
           n /= aZahlen[i];
        // So that the first time is not *
           if (f != 0)
              System.out.print(" * " + aZahlen[i]);
           else
              System.out.print(aZahlen[i]);
           i--;
        }
        // So that f remains zero if no division by 2
        else
           f--;
     }
     System.out.println();
  }

}

在哪里可以節省一些資源? 順便說一句,我現在只能使用數組...對不起,德國的評論。 就算有一些真正不必要的長循環或類似的東西引起您的注意

謝謝!

我最多只搜索(int) sqrt(n) ,而不是最多搜索n-1 (int) sqrt(n) 弄清楚為什么這足以滿足您的需求。 ;-)

我不明白為什么您根本需要altesP 您不能僅將p增加2嗎?

我不會通過刪除來過濾。 我會建立一個肯定的列表,並添加您找到的素數。

研究快速素數測試,該測試可以排除一個數而不必經歷整個篩子。

因此,請對您的代碼進行以下更改:

  1. 建立primes列表而不是刪除aZahlen sqrtN = (int)sqrt(n)因為分配大小應該很好,並使用一個foundPrimes計數來知道您知道多少個素數。

  2. 遍歷p直到<= sqrtN而沒有任何絨毛。 查看是否有已知質數是除數,否則您發現了新質數。 輸出它,並將其存儲在foundPrimes列表中。

一個int[]每個值使用32位。 如果使用byte[] ,則每個值將使用8位;如果使用BitSet,則每個值將使用1位(小32倍)

我不確定您要做什么。 我認為您正在嘗試通過質數除以試算的整數。 為此,您不需要所有小於整數的質數,僅需要小於整數平方根的質數,因此,您需要的是一個簡單的Eratosthenes篩子來選擇質數:

function sieve(n)
  bits := makeArray(2..n, True)
  ps := []
  for p from 2 to n
    if bits[p]
      ps.append(p)
      for i from p+p to n step p
        bits[i] = False
  return ps

然后,您可以使用這些質數執行分解:

function factors(n)
  ps := primes(sqrt(n))
  fs := []
  p := head(ps)
  while p*p <= n
    if n%p == 0
      fs.append(p)
      n := n / p
    else
      ps := tail(ps)
      p := head(ps)
  fs.append(n)
  return fs

我在博客中的一篇文章中討論了用質數編程,其中包括這兩種算法在Java中的實現。 這篇文章還包括上面列舉的其他更有效的枚舉質數和分解整數的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM