【问题标题】:Why is my program giving me all the non-prime numbers when I ask for prime numbers?当我要求质数时,为什么我的程序给了我所有的非质数?
【发布时间】:2013-08-17 18:00:14
【问题描述】:

我想使用位数组和埃拉托色尼筛算法来查找一定范围内的所有素数。我的代码可以编译,但它会打印所有非素数而不是素数(2 除外,因为我要求我的 Sieve 函数打印 2)。有人可以查看我的代码并给我一些关于如何修复它的提示吗?非常感谢您的帮助。谢谢!

注意:我的作业要求是使用位数组。

#include <stdio.h>
#include <stdlib.h>

//#define MAXBYTES 1000000
#define MAXBYTES 10


void setBit(unsigned int A[], int k);
unsigned getBit(unsigned int A[], int k);
void print_prime (int prime_num);
void sieve_Prime(unsigned int bit_arr[]);

int main (int argc, char** argv)
{
    //int bit_arr[MAXBYTES];      //This is the bit array (32 X MAXBYTES)
    unsigned int bit_arr[MAXBYTES];      //or bit_arr[MAXBYTES]
    int i;

    for (i=0; i < MAXBYTES; i++)
    {
        bit_arr[i] = 0x00;            //initialize all bits to 0s
    }

    setBit(bit_arr, 0);             //0 is not prime, set it to be 1
    setBit(bit_arr, 1);             //1 is not prime, set it to be 1

    sieve_Prime(bit_arr);
    printf("\n");

    return 0;

}

//Set the bit at the k-th position to 1
void setBit(unsigned int A[], int k)
{
    int i = k/32;
    int pos = k % 32;

    unsigned int flag = 1;      //flag = 0000 ..... 00001
    flag = flag << pos;         //flag = 0000...010...000 (shifted k positions)

    A[i] = A[i] | flag;         //Set the bit at the k-th position in A[i];
}

//get the bit at the k-th position
unsigned getBit(unsigned int A[], int k)
{
    int i =k/32;
    int pos = k % 32;

    unsigned int flag = 1;

    flag = flag << pos;

    if (A[i] & flag)
        return 1;
    else
        return 0;
}


void print_prime (int prime_num)
{
    //print a prime number in next of 8 columns
    static int numfound=0;

    if (numfound % 8 == 0)
        printf("\n");
    if (prime_num+1 < MAXBYTES*8)
        printf("%d\t", prime_num);
    numfound++;
}

void sieve_Prime(unsigned int bit_arr[])
{
    int i;
    int k;
    int next_prime = 2;

    print_prime(2);

    while (next_prime+1 < MAXBYTES*8)
    {
        k = next_prime;

        //multiples of next_prime is not primpe
        while(next_prime*k < MAXBYTES*8)
        {
            setBit(bit_arr, next_prime*k);      //set it to be 1
            k++;     
        }

        //find next_prime by skipping non-prime bits marked 1
        while (next_prime + 1 < MAXBYTES*8 && getBit(bit_arr, ++next_prime))
        {
            print_prime(next_prime);
        }
    }
}

【问题讨论】:

    标签: c primes sieve-of-eratosthenes


    【解决方案1】:

    问题在于你的循环:

    while (next_prime + 1 < MAXBYTES*8 && getBit(bit_arr, ++next_prime))
    {
        print_prime(next_prime);
    }
    

    您在设置位时继续打印东西(即,当您知道它不是素数时)。所以基本上,你的循环是“打印我在寻找下一个素数时找到的所有数字”,而不是“在循环中查找下一个素数,然后打印下一个素数”。

    我怀疑你想要类似的东西:

    next_prime++; // We always want to at least move on once...
    while (next_prime + 1 < MAXBYTES*8 && getBit(bit_arr, next_prime))
    {
        next_prime++;
    }
    print_prime(next_prime);
    

    我还没有检查代码是否有问题全部,但这肯定是要修复的初始问题。

    【讨论】:

    • 感谢您的提示。我试过你的建议,没有用。我得到一堆2s。还有其他建议吗?
    • @user2203774:你试过调试吗?你需要学会诊断问题。您很可能在循环之前需要一个无条件的next_prime++; - 将其编辑到我的答案中。
    • 谢谢。我对编程很陌生。我想了解有关调试的更多信息。我会调查的。
    【解决方案2】:

    您可以简单地通过添加下一个初始化构造来初始化具有零值的数组:

    unsigned int bit_arr[MAXBYTES] = { };
    

    然后数组的每个成员都将保持零值。另外,尽量避免printf("\n");之类的东西。如果一次只需要输出一个符号,最好使用putchar('\n')

    此外,如果您不在此翻译单元之外使用此例程,您可以将 static 关键字添加到您的工作函数原型和定义中,main 函数除外。

    【讨论】:

      猜你喜欢
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      相关资源
      最近更新 更多