【问题标题】:faster Sieve of Erathostenes and prime number factorization in JavaJava中更快的Eratosthenes筛和素数分解
【发布时间】:2012-12-01 12:55:28
【问题描述】:

我的输入是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();
  }

}

我在哪里可以节省一些资源?顺便说一句,我现在只能使用数组...对不起德国 cmets。只是如果一些真正不必要的长循环或类似的东西引起了你的注意

谢谢!

【问题讨论】:

  • 与其为德国cmets道歉,不如翻译一下?
  • @TheSmose 很明显,OP 会说英语。
  • 天哪,第一篇文章,JonSkeet 发表了第一条评论,Marko Topolnik 编辑 :) 幸运儿
  • @TheSmose 为什么会说德语和英语的人需要 Google 翻译 的服务?是的,您的评论另有说明。

标签: java primes factorization sieve


【解决方案1】:

我不会搜索到n-1,而是只搜索到(int) sqrt(n)。 自己弄清楚为什么这就足够了。 ;-)

我完全不明白你为什么需要altesP。你不能把p 加二吗?

我不会通过删除来过滤。我会建立一个肯定列表,并添加您找到的素数。

研究快速素数测试,无需通过整个筛子即可排除一个数字。

请对您的代码进行以下更改:

  1. 不要删除aZahlen,而是建立primes 的列表。 sqrtN = (int)sqrt(n) 作为分配大小应该没问题,并使用计数 foundPrimes 来计算您知道多少个素数。

  2. 迭代 p 直到 &lt;= sqrtN 没有任何模糊。看看是否有任何已知的素数是除数,否则你找到了一个新的素数。输出它,并将其存储在您的foundPrimes 列表中。

【讨论】:

    【解决方案2】:

    int[] 每个值使用 32 位。如果您使用byte[],这将使用每个值 8 位,如果您使用 BitSet,它将使用每个值 1 位(小 32 倍)

    【讨论】:

    • 他没有内存不足。 int[] 可能比 byte[] 快​​(而且他可能需要测试大于 127 的素数!)并且肯定比 BitSet 快。
    【解决方案3】:

    我不确定你想做什么。我认为您正在尝试通过素数的试除法来分解整数。为此,您不需要所有小于整数的素数,只需要小于整数平方根的素数,因此您只需要一个简单的 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
    

    我在博客的essay 中讨论了使用素数进行编程,其中包括这两种算法在Java 中的实现。这篇文章还包括其他更有效的枚举素数和分解整数的方法。

    【讨论】:

    • 使用主要参数调用 factors 将导致使用空列表调用 head,是吗?根据使用的语言,这可能会导致运行时错误(例如,在 Scheme 中调用 (factors 29))。
    • 如果你试图分解一个素数,你应该得到任何发生在你身上的事情。
    猜你喜欢
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多