Java 用Eratosthenes筛生成k素数
查看了一些实现并发现,奇怪为什么从k=m*m开始迭代是安全的?谢谢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的循环中设置 对
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都是