我需要一个更好的主要检查算法

时间:2014-05-11 19:35:18

标签: java algorithm optimization solution

My prime pattern

Primes真的很奇怪......我用无聊创造了这个简单的模式。我没有在网上看到任何相似之处。如您所见,图片的缺失线取决于您选择的比例,范围从值1到1000000

我打算从价值1 - 25,000,000,也许是1 - 10,000,000,000

也许使用筛选技术会有所帮助,但是我需要一个足够的java实现,我使用经典的质量检查器,它由2个for循环组成,它们确实能够节省时间。

编辑:这是我的代码示例

 boolean checkPrime(long a)
 {
 long count = 0L;
    for(long op = 1;op<=a;op++)  
            if(a%op==0)
                     count++;

  return count ==2;
 }

更新:我找到了一个针对我的代码的简单优化措施

 boolean checkPrime(long a)
 {
 long count = 0L;
    for(long op = 1;op<=a;op++)  
            if(a%op==0)
                      {
                       count++;
                               if(count>2)break; //here it is
                      }

  return count ==2;
 }

代码似乎运行x10更快

我最终选择了创造它并坚持下去。

package superprime;
public class SuperPrime {
    static java.util.List primes = new java.util.ArrayList<Long>();
    public static void main(String[] args) {
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        long start = System.currentTimeMillis();
       primes.add(2);
       boolean flag = true;
       long u =primes.size();long wow;double val;
    for(long e = 3L; e<10000000;e=e+2){
        flag = true;
        for( wow = 0;(wow< u)&&flag;wow++){
            if(e%(Long.parseLong(primes.get((int)wow)+""))==0)
           flag=false;

        }
        if(flag)primes.add(e);
        val = Double.parseDouble(primes.get((int)u)+"");
        if((val == Math.sqrt(e+1))||(val == Math.sqrt(e+2)))u++;
   // if(e%250000==0)System.out.println((System.currentTimeMillis()-start)/1000.0+" @ "+e);
    }long end =System.currentTimeMillis();
     System.out.println(""+(end-start)/1000.0);
     wow = 1;
for(Object h : primes)System.out.println(++wow+"\t"+(Long.parseLong((h)+"")));

    }

}

2 个答案:

答案 0 :(得分:2)

您提供的代码是为每个人制作一个操作。 这是改善它的简单方法:

boolean checkPrime(long a)
 {
 long count = 0L;
 for(long op = 2;op*op<=a;op++)  
        if(a%op==0)
                 return false;

  return true;
 }

现在它只进行sqrt(a)操作并始终给出正确的答案。对于beter执行时间是随机算法,如Rabin-Milers算法:http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

我在Rabin-Milers算法的c ++中包含了我的实现。

#include<iostream>
#include<cmath>
#include<cstdlib>
using namespace std;

const int losowania=20;

long long pote(long long x,long long k,long long m)//this function is counting (x^k)mod m
{
if(k==1)
{
    return x%m;
}
if(k%2==0)
{
    long long a=pote(x,k/2,m);
    return ((__int128_t)((__int128_t)a*(__int128_t)a)%(__int128_t)m);
}
else
{
    long long a=pote(x,k-1,m);
    return ((__int128_t)((__int128_t)a*(__int128_t)x)%(__int128_t)m);
}
}

bool Rabin_Miler(long long p,long long x)
{

if(pote(x,p-1,p)!=1)
{
    return false;
}
long long wyk=(p-1);
while(wyk%2==0)
{
    wyk/=2;
}
long long teraz=pote(x,wyk,p);
if(teraz==1)
{
    return true;
}
while(teraz!=1&&teraz!=p-1)
{
    teraz=(__int128_t)((__int128_t) teraz*(__int128_t)teraz)%(__int128_t)p;
}
if(teraz==1)
{
    return false;
}
else
{
    return true;
}
}

bool is_prime(long long p)
{
srand(100);
    for(int i=0;i<losowania;i++)
    {
        if(!Rabin_Miler(p,(rand()%(p-1))+1))
        {
            return false;
            break;
        }
    }
return true;
}

答案 1 :(得分:1)

如果你想找到每个素数,那么你可以使用一个版本的mosthmus'sieve来生成前1000个左右,然后只检查先前素数列表,因为它们是基本定理的唯一有意义的因素代数。如果你想找到所有质数,这几乎肯定比使用一般数字筛子更快,这种筛子设计用于在你没有素数列表时有效地计算大数。这是我为Euler Project Number 7编写的一些东西。它有两个函数,一个使用mosthmus'sieve来查找高达1000的所有素数,然后它使用素数列表作为输入来顺序工作下一个数字通过对素数列表的试验划分是主要的。

public class NthPrime {

/**
 * @param args
 */
public static void main(String[] args) 
{
    int N = 10001;
    long startTime = System.currentTimeMillis();
    ArrayList<BigInteger> firstPrimes = primes(1000);
    System.out.println("The "+N +"th Prime is: " + Nthprime(firstPrimes, N));
    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    System.out.println(firstPrimes.toString());
    System.out.println(elapsedTime);

}

public static BigInteger Nthprime(ArrayList<BigInteger> primes, int N)
{
    if(N < primes.size())
    {

        return primes.get(N-1);

    }



    BigInteger start = primes.get(primes.size()-1);
    boolean bool = true;
    BigInteger ZERO = new BigInteger("0");
    BigInteger ONE = new BigInteger("1");
    BigInteger j = new BigInteger("1");
    while(bool)
    {
        boolean hasfactor = false;
        for(int i=0; i<primes.size(); i++)
        {

            BigInteger Q = start.add(j);
            BigInteger remainder = Q.mod(primes.get(i));

            if(remainder.equals(ZERO))
            {
                hasfactor = true;
                break;
            }
        }

        if(!hasfactor)
        {
            primes.add(start.add(j));

        }

        if(primes.size() == N)
        {
            bool = false;
        }

        j = j.add(ONE);
    }

    return primes.get(primes.size()-1);

}


public static ArrayList<BigInteger> primes(int N)
{
    boolean[] primes = new boolean[N+1];


    for(int j = 0; j<N+1; j++)
    {
        primes[j] = true;
    }
    int i = 2;
    while(i < N+1)
    {
     if(primes[i])
        {
            int j = 2*i;
            while(j<N+1)
            {
                primes[j] = false;
                j = j+i;

            }
        }
     i++;
    }
    ArrayList<BigInteger> allprimes = new ArrayList<BigInteger>();
    for(i=2; i<N+1; i++)
    {
        if(primes[i])
        {
            allprimes.add(new BigInteger((new Integer(i)).toString()));
        }
    }

    return allprimes;


}

}