Performance 更快的素代C#
我知道关于同一个话题已经有很多问题了,但这一个可能不同。我研究了一些计算从2到N的素数的算法。我编写了以下算法来计算范围内的素数,比如从Performance 更快的素代C#,performance,algorithm,c#-4.0,primes,sieve-of-eratosthenes,Performance,Algorithm,C# 4.0,Primes,Sieve Of Eratosthenes,我知道关于同一个话题已经有很多问题了,但这一个可能不同。我研究了一些计算从2到N的素数的算法。我编写了以下算法来计算范围内的素数,比如从N到M,其中M可以大到10^10,N和M之间的差可以10^6 for (k = 0; k < t; k++) { int[] indexOfPrimes = new int[m[k] - n[k] + 1]; int index_1=2; int index_2=0; int counter = 0; for (
N
到M
,其中M可以大到10^10
,N和M之间的差可以10^6
for (k = 0; k < t; k++)
{
int[] indexOfPrimes = new int[m[k] - n[k] + 1];
int index_1=2;
int index_2=0;
int counter = 0;
for (index_1 = 2; index_1 < Math.Sqrt(m[k]); index_1++)
{
counter = 0;
for (index_2 = index_1*index_1; index_2 <= m[k];)
{
if (index_2 >= n[k] && index_2 <= m[k])
indexOfPrimes[index_2 % (m[k] - n[k] + 1)] = 1;
index_2 = (index_1 * index_1) + (index_1 * ++counter);
}
}
for (i = n[k]; i <= m[k]; i++)
{
if (i == 1)
continue;
if (indexOfPrimes[i % (m[k] - n[k] + 1)] != 1)
Console.WriteLine(i);
}
Console.WriteLine("\n");
}
(k=0;k
{
int[]indexOfPrimes=新的int[m[k]-n[k]+1];
int指数_1=2;
int指数_2=0;
int计数器=0;
对于(索引_1=2;索引_1 从算法的角度来看,(index_2=index_1*index_1;index_2=n[k]&&index_2),您要做的是
- 使用任何方法查找介于2和316之间的素数
- 使用这些素数筛选100000以下的所有数字,从而找到100000以下的素数
- 使用100K素数筛选给定范围,从而找到给定范围内的素数
为了用一个例子来说明最后一点,假设我们知道从2到4的所有素数,我们想找到11到15之间的所有素数。第一步是找到2到4之间的素数集,即{2,3}
。现在我们使用该集来筛选集{11,12,13,14,15}
为此,我们注意到6*2是期望范围内2的最小倍数,然后我们消除所有2的倍数,直到达到范围的末尾,所以12和14被消除
然后我们用3重复这个过程,去掉12(再次)和15。剩下的数字是11和13,所以这些是11到15范围内的素数
一个挑战是找到一个给定素数p
的最小倍数,该倍数在N
到M
的范围内。您可以通过将范围的低端除以p
并在必要时进行四舍五入来实现。例如,下面的代码找到最小的乘数x
,从而p*x>=N
>
int p, N, x;
x = N / p; // integer division truncates, so x may be too small
if ( p * x < N ) // if p divides N, then p * x == N,
x++; // otherwise we need to adjust x
Example 1: (N = 11, p = 2) ==> (x = 5, but 5*2<11, so x = 6)
Example 2: (N = 12, p = 3) ==> (x = 4, and 3*4==12, so x stays at 4)
intp,N,x;
x=N/p;//整数除法截断,因此x可能太小
如果(p*x(x=5,但5*2(x=4,3*4==12,所以x保持在4)
素数p大于界lo的最小倍数是下限(lo/p)*p+p
。你可以用它作为起点,而不是从p开始。我的范围不是静态的。它可以是10-100000或100000-200000或100000000-100100000。但我想我明白了你的意思。首先,我应该得到sqrt(n[k])
,对吗?@SamarthAgarwal 316是sqrt(100K)
,100K是sqrt(10^10)
。关键是如果你知道所有100K以内的素数,你可以筛选任何10^10以内的范围。你是说我必须检查317到100K之间的每个数被范围(2-317)内的每个素数整除吗?@SamarthAgarwal从2到317的素数可用于筛选318到100000的数。这相当于在100K数组上运行eratosthenes
筛选,并在到达p>316
@SamarthAgarwal时停止,因此需要一个大小为(M-N+1)的数组这表示从N到M的数字,您使用高达100K的素数来筛选该数组。这是SPOJ的问题吗?从描述来看是这样的。是的,我超过了时间限制。您的笔记本电脑可能比SPOJ电脑快6倍。这是错误的;我忘了乘以p。现在已经解决了。对不起,谢谢。您的回复r帮助我将速度提高了2倍。但是我仍然得到了错误的答案,尽管我所有的测试,不管它们有多大,都是完美的。我不会费力地阅读你的代码。但是如果你的答案很接近,你可能会在某个地方出现一个错误,也许你没有标记范围内的最后一个组合。我已经检查过了,目前还没有找到任何东西.