【问题标题】:Sieve of Eratosthenes and his primes埃拉托色尼筛法和他的素数
【发布时间】:2016-11-05 19:57:07
【问题描述】:

这是我的代码:

#include <stdio.h>

int main() {
    int number;
    int prime[200000] = { 0 };
    int i = 0;
    int j = 0;
    int number1[200] = { 0 };
    int t = 0;
    int count = 0;
    int newprime2[200][200];
    int counter[200] = { 0 };
    int square;
    int count1;

    while ((scanf("%d", &number) ==  1 ) && (number != 0)) {
        number1[count] = number;
        ++count;
    }
    count1 = count;
    for (count = 0; count < count1; ++count) {
        if (number1[count] < 0) {
            fprintf(stderr, "Error: Invalid input!\n"); 
            return 100;
            break;
        }
        for (i = 0; i < number1[count]; i++) {
            prime[i] = i;
        }
        for (i = 2; (i < (number1[count])); i++) {
            if (prime[i] != 0) {       
                for (j = 2; (j < (number1[count])); j++) {
                    {
                        prime[j*prime[i]] = 0;
                        if (prime[i] * j > (number1[count]))
                            break;
                    }
                }
            }
        }
        t = 0;
        for (i = 2; i < number1[count]; ++i) {
            if ((prime[i] != 0) && (number1[count] % prime[i] == 0)) {
                newprime2[count][t] = prime[i];
                ++t; 
            }
        }
        printf("\n");
        printf("%i is made out of these primes\n", number1[count]);
        counter[count] = 0;
        square = 0;

        for (i = 0; i < t; ++i) {
            while (number1[count] % newprime2[count][i] == 0) {
                number1[count] = number1[count] / newprime2[count][i];
                square++;
            }
            counter[count]++;
            /* if number isn't made out of any of these primes*/
            if (!newprime2[count][i]) {   /*Why is this not working?*/
                printf("%i ", number1[count]);
            }  
            if (counter[count] == 1) {
                printf("%i^%d ", newprime2[count][i], square);
            }  else {
                printf("* %i^%d ", newprime2[count][i], square);
            }
            square = 0;
        }
    }
    printf("\n");

    return 0;
}

例如,我的输入是:1 11 120 8 0

输出如下所示:

1 is made out of these primes
11 is made out of these primes
120 is made out of these primes
2^3 * 3^1 * 5^1 
8 is made out of these primes
2^3

但输出应如下所示:

1 is made out of these primes
1
11 is made out of these primes
11
...

声明(!newprime2[count][i]) 表示这个数组是空的吧?那么为什么它不起作用呢?为什么我什至不能使用 gcc -pedantic -Wall -Werror -std=c99 -O3 ?有人可以帮我吗?

【问题讨论】:

  • 对我来说 gcc -pedantic -Wall -Werror -std=c99 -O3 运行良好,您的代码编译时不会出现错误或警告。

标签: c primes sieve-of-eratosthenes


【解决方案1】:

查看这部分代码:

    t = 0;
    for (i = 2; i < number1[count]; ++i){
        if ((prime[i]!=0) && (number1[count] % prime[i]==0)){
            newprime2[count][t] = prime[i];
            ++t;
        }

如果number1[count]1,那么for 循环的主体不会执行,所以t 将保持其值(0)。因此是下一个循环的主体

        for (i=0; i < t; ++i){

也不会执行。

对于数字11,此循环的主体执行,但它会什么都不做,因为if 语句中的条件将是总是@ 987654330@。所以它会导致 同样的问题 - t 将保持其值 0 具有相同的结果。

【讨论】:

    【解决方案2】:

    线

    if (!newprime2[count][i]) 
    

    如果t==0for 循环之前没有达到,并且输入是素数或单位时就是这种情况。只需检查t,如果为零就到此为止。

    或者早点检查它是统一的还是已经在prime中。

    我不能重复您对gcc -pedantic -Wall -Werror -std=c99 -O3 的问题。

    【讨论】:

      【解决方案3】:

      您的算法既过于复杂又过于近似:

      • 您不需要执行筛选来分解数字,您只需枚举除数,复合除数的余数将不为零,因为它们的质因数已经被删除。

      • 筛子不完整:你转到200000,如果int 类型是32 位(46341 就足够了),那将是矫枉过正,如果int 是64 位,则太小。

      这是一个简化版:

      #include <stdio.h>
      
      int main(void) {
          int number, i, p, n, factors, count;
          int numbers[200];
      
          for (count = 0; count < 200 && scanf("%d", &number) ==  1; count++) {
              if (number == 0)
                  break;
              if (number < 0) {
                  fprintf(stderr, "Error: Invalid input!\n");
                  return 100;
              }
              numbers[count] = number;
          }
          for (i = 0; i < count; i++) {
              number = numbers[i];
              printf("%d is made out of these primes\n", number);
              factors = 0;
              for (p = 2; p * p <= number; p += 1 + (p & 1)) {
                  if (number % p == 0) {
                      n = 0;
                      factors++;
                      do {
                          number /= p;
                          n++;
                      } while (number % p == 0);
                      if (n == 1)
                          printf("%d ", p);
                      else
                          printf("%d^%d ", p, n);
                  }
              }
              if (factors == 0 || number != 1)
                  printf("%d", number);
              printf("\n");
          }
          return 0;
      }
      

      【讨论】:

      • @JozefSkála:你提供输入值了吗?它在我的系统上按预期工作。
      • 是的,例如 120 0。程序停止并且没有打印任何内容(我正在使用 gcc -pedantic -Wall -Werror -std=c99 -O3 如果这可能是问题)
      • 我在 OS/X 和 Debian Linux 上都试过了。它输出212 is made out of these primes 2^2 53。你是从命令行运行它吗?
      • 是的,我是。终端(Ubuntu)。有问题吗?
      • 不,不应该。您是从网站上搜索并粘贴还是重新输入?如果输入负数会发生什么?
      猜你喜欢
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多