【问题标题】:C: Sieve of Eratosthenes using arraysC:使用数组的 Eratosthenes 筛
【发布时间】:2012-03-19 05:34:48
【问题描述】:

我正在执行 C 编程任务以在不使用 C 的平方根函数的情况下实现 Eratosthenes 的 Sieve。下面是我的输出和我的教授的输出,我不确定我的代码中是什么导致它出错。有任何想法吗?

这是预期的输出

Program initiated
   1   2   3   5   7  11  13  17  19  23  29  31
  37  41  43  47  53  59  61  67  71  73  79  83
  89  97 101 103 107 109 113 127 131 137 139 149
 151 157 163 167 173 179 181 191 193 197 199 211
 223 227 229 233 239 241 251 257 263 269 271 277
 281 283 293 307 311 313 317 331 337 347 349 353
 359 367 373 379 383 389 397 401 409 419 421 431
 433 439 443 449 457 461 463 467 479 487 491 499
 503 509 521 523 541 547 557 563 569 571 577 587
 593 599 601 607 613 617 619 631 641 643 647 653
 659 661 673 677 683 691 701 709 719 727 733 739
 743 751 757 761 769 773 787 797 809 811 821 823
 827 829 839 853 857 859 863 877 881 883 887
Program terminated

这是我的输出:

Program initiated
   1  37  41  43  47  53  59  61  67  71  73  79
  83  89  97 101 103 107 109 113 127 131 137 139
 149 151 157 163 167 173 179 181 191 193 197 199
 211 223 227 229 233 239 241 251 257 263 269 271
 277 281 283 293 307 311 313 317 331 337 347 349
 353 359 367 373 379 383 389 397 401 409 419 421
 431 433 439 443 449 457 461 463 467 479 487 491
 499 503 509 521 523 541 547 557 563 569 571 577
 587 593 599 601 607 613 617 619 631 641 643 647
 653 659 661 673 677 683 691 701 709 719 727 733
 739 743 751 757 761 769 773 787 797 809 811 821
 823 827 829 839 853 857 859 863 877 881 883 887
Program terminated

这是我的代码:

#include <stdio.h>

void zap(int data[], int divisor)
{
    for(int i=0;i<900;i++)
    {
        if(data[i]%divisor==0) // if mod is not 0, 0 out the index. 
        {
            data[i] = 0; 
        }
    }
}
// the display method 
void display(int data[])
{
    int count = 0; // init counter on the out side
    for(int i=0;i<900;i++)
    {
        if(data[i]>0)// don't print 0s
        {
            printf("%4d",data[i]);// print the data in a column 

            count++;// increment count 

            if(count==12) // print rows and columns 
            {
                count=0; // reset count
                printf("\n"); // print new line 
            }
        }
    }
    if(count<12)// we terminate loop and we now need print a new line 
    {
        printf("\n"); 
    }
}

int main()
{   
    // start the program, with a message
    printf("Program initiated\n"); 

    // needs to be 900 long 
    int primes[900];

    // populate the array 
    for(int i=1; i <= 900; i++)
    {
            primes[i] = i; 
    }

    // elminate the bad numbers 
    for(int i=2; i < 35; i++)
    {
        zap(primes,i); 
    }

    // display the array. 
    display(primes);

    // print the end message    
    printf("Program terminated\n"); 

    return 0; 
}

【问题讨论】:

  • 只是一个简短的评论:我认为你根本没有实现 sieve - 对于这个算法,你一次取一个数字并 remove i> 您将查看的数字列表中该数字的倍数 - 看到不涉及除法,只涉及乘法和查找 - 另一方面,您使用除以余数 ...
  • 顺便说一句:至于为什么您的 versino 不起作用:记住 i%i==0 (修改所有内容)并查看对“zap”的调用(最多 35,其中 36 = 3*12) ...
  • Ummm....1 不是质数。
  • C 数组的索引从 0 到 N-1,您在第一个循环“填充”中写入边界
  • 那个程序没有实现埃拉托色尼筛算法。 Wikipedia 有一个非常有用的动画,它显示了它的工作原理,并详细解释了它。

标签: c sieve-of-eratosthenes


【解决方案1】:

您的zap 函数将始终删除输入值。例如,当您使用除数 2 调用 zap 时,它会检查 2%2,找到 0,然后将其删除,即使 2 是素数。

要解决这个问题,您可以让它在divisor+1 开始跳动。

但是,我注意到它实际上根本没有做筛子。 zap 不需要做任何模数,只需按divisor 的步骤遍历数组即可。仔细检查埃拉托色尼筛实际上是什么。

【讨论】:

    【解决方案2】:

    这不是真正的 Eratosthenes 筛子。该算法的要点是完全避免测试可除性(使用%盲目地(即不进行任何计算)排除除 2 之外的每 2 个数字,然后除 3 之外的每 3 个数字,然后除 3 之外的每 4 个数字4 以此类推。

    你需要修复zap函数:首先,如果它等于divisor,不要删除数字,并且不要检查余数,只需删除数字。

    【讨论】:

    • 除 4 之外的每 4 个数字?但 4 不是素数
    • 哦,是的。好吧,我读错了。那时我读错了。我在除两个之外的每个第二个数字的上下文中阅读它,因为那个是质数..哎呀,哈哈。
    【解决方案3】:

    你可以使用这样的东西:

    (将筛子初始化为足够大的布尔数组,每个条目都设置为 true - 因为我想保持简单设置 sieve[0] = false; sieve[1] = false;

    for(int i = 2; i < endOfNumbers; i++)
    {
       if (sieve[i] == false) continue;
       for (int m = 2*i; m < endOfNumbers; m += i)
          sieve[m]=false;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 1970-01-01
      相关资源
      最近更新 更多