Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 更快的素代C#_Performance_Algorithm_C# 4.0_Primes_Sieve Of Eratosthenes - Fatal编程技术网

Performance 更快的素代C#

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 (

我知道关于同一个话题已经有很多问题了,但这一个可能不同。我研究了一些计算从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 (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倍。但是我仍然得到了错误的答案,尽管我所有的测试,不管它们有多大,都是完美的。我不会费力地阅读你的代码。但是如果你的答案很接近,你可能会在某个地方出现一个错误,也许你没有标记范围内的最后一个组合。我已经检查过了,目前还没有找到任何东西.