Java 用Eratosthenes筛生成k素数

Java 用Eratosthenes筛生成k素数,java,algorithm,primes,Java,Algorithm,Primes,查看了一些实现并发现,奇怪为什么从k=m*m开始迭代是安全的?谢谢 public void runeratosthenessive(int上限){ int upperBoundSquareRoot=(int)Math.sqrt(上限); boolean[]isComposite=new boolean[上限+1]; 对于(int m=2;m每一个小于m*m且m是因子的复合数,例如m*n,其因子小于m,例如n,我们已经将其标记为复合 这适用于素数或复合n,对于素数n,我们在m=n的循环中设置 对

查看了一些实现并发现,奇怪为什么从k=m*m开始迭代是安全的?谢谢

public void runeratosthenessive(int上限){
int upperBoundSquareRoot=(int)Math.sqrt(上限);
boolean[]isComposite=new boolean[上限+1];

对于(int m=2;m每一个小于m*m且m是因子的复合数,例如m*n,其因子小于m,例如n,我们已经将其标记为复合

这适用于素数或复合n,对于素数n,我们在m=n的循环中设置


对于复合n:我们知道任何大于1的整数都可以表示为素因子的乘积。其中一个素因子是n的最小素因子,我们称之为s。因为s是n的素因子,我们可以将n表示为s*r,对于一些r。这也意味着m*n是m*s*r。s 这适用于素数或复合n,对于素数n,我们在m=n的循环中设置


对于复合n:我们知道任何大于1的整数都可以表示为素因子的乘积。其中一个素因子是n的最小素因子,我们称之为s。因为s是n的素因子,我们可以将n表示为s*r,对于一些r。这也意味着m*n是m*s*r。s
  • 1 x 120
  • 2 x 60
  • 3 x 40
  • 4 x 30
  • 5 x 24
  • 6 x 20
  • 8 x 15
  • 10 x 12
现在,一个观察:sqrt(120)=11(发言)

现在,下一个观察结果,
上述每个因子都有一个共同点,即一个因子小于11,另一个大于11

现在让我们将36分解为:

  • 1 x 36
  • 2 x 18
  • 3 x 12
  • 4 x 9
  • 6 x 6
sqrt(36)=6。同样,我们可以做一个类似的观察,每一个因子都有一个小于6的数,还有一个大于6的数,除了
6x6
,因为36是正方形

因此,我们可以很容易地推断出:

对于任何数字,如果它不是质数,我们总是可以找到(至少)它的一个因子,如果我们去它的平方根

所以,为了降低复杂性,我们需要一直到范围内每个数字的平方根,所以,
sqrt(上限)
对于外循环来说就足够了。这是因为,如果到那时为止任何数字都没有标记为复合数,这将永远不会是因为我们已经考虑了所有可能的因子

编辑:

也可以说,这个筛选器的实现不是代码>优化的< /C> >。不是在渐近复杂性方面,而是可以减少一些操作。我将在C++中添加筛选器的实现,它计算所有素数直到Max。

#define MAX 1000000
#define I int
#define FOR(i,a,b) for(i=a;i<b;i++)
I p[MAX]={1,1,0};            //global declaration
I prime[MAX/10]={2};         //global declaration
void sieve()
{
    I i,j,k=1;
    for(i=3;i*i<=MAX;i+=2)
    {
        if(p[i])
            continue;
        for(j=i*i;j<MAX;j+=2*i)
            p[j]=1;
    }
    for(i = 3; i < MAX; i+=2)
    {
        if(!p[i])
            prime[k++]=i;
    }
    return;
}
#定义最大1000000
#定义I int

#定义(i,a,b)FOR(i=a;i让我们取一个数字并将其分解:例如120

  • 1 x 120
  • 2 x 60
  • 3 x 40
  • 4 x 30
  • 5 x 24
  • 6 x 20
  • 8 x 15
  • 10 x 12
现在,一个观察:sqrt(120)=11(发言)

现在,下一个观察结果,
上述每个因子都有一个共同点,即一个因子小于11,另一个大于11

现在让我们将36分解为:

  • 1 x 36
  • 2 x 18
  • 3 x 12
  • 4 x 9
  • 6 x 6
sqrt(36)=6。同样,我们可以做一个类似的观察,每一个因子都有一个小于6的数,还有一个大于6的数,除了
6x6
,因为36是正方形

因此,我们可以很容易地推断出:

对于任何数字,如果它不是质数,我们总是可以找到(至少)它的一个因子,如果我们去它的平方根

所以,为了降低复杂性,我们需要一直到范围内每个数字的平方根,所以,
sqrt(上限)
对于外循环来说就足够了。这是因为,如果到那时为止任何数字都没有标记为复合数,这将永远不会是因为我们已经考虑了所有可能的因子

编辑:

也可以说,这个筛选器的实现不是代码>优化的< /C> >。不是在渐近复杂性方面,而是可以减少一些操作。我将在C++中添加筛选器的实现,它计算所有素数直到Max。

#define MAX 1000000
#define I int
#define FOR(i,a,b) for(i=a;i<b;i++)
I p[MAX]={1,1,0};            //global declaration
I prime[MAX/10]={2};         //global declaration
void sieve()
{
    I i,j,k=1;
    for(i=3;i*i<=MAX;i+=2)
    {
        if(p[i])
            continue;
        for(j=i*i;j<MAX;j+=2*i)
            p[j]=1;
    }
    for(i = 3; i < MAX; i+=2)
    {
        if(!p[i])
            prime[k++]=i;
    }
    return;
}
#定义最大1000000
#定义I int

#为(i,a,b)定义为(i=a;我认为在这种情况下,只要n是素数?或者无论n是什么(复合或素数)?如果n是复合的,那么当使用n的最小素数因子时,n*m就会被标记。谢谢moreON,你的意思是假设n=pow(p1,x1)*pow(p2,x2),p1和p2都是