C - 使用此算法获取素数

时间:2017-05-26 16:11:20

标签: c primes

我正在打一些简单的问题。 我想获得素数

我将使用此算法
enter image description here

和...我完成了这样的代码编写。

int k = 0, x = 1, n, prim, lim = 1;
int p[100000];
int xCount=0, limCount=0, kCount=0;

p[0] = 2;
scanf("%d", &n);

start = clock();
do
{
    x += 2; xCount++;
    if (sqrt(p[lim]) <= x)
    {
        lim++; limCount++;
    }
    k = 2; prim = true;
    while (prim && k<lim)
    {

        if (x % p[k] == 0)
            prim = false;
        k++; kCount++;
    }
    if (prim == true)
    {
        p[lim] = x;
        printf("prime number : %d\n", p[lim]);
    }
} while (k<n);

我想查看这段代码的重复次数(x + = 2; lim ++; k ++;) 所以我使用了xCount,limCount,kCount变量。

当输入(n)为10时,结果为x:14,lim:9,k:43。错误答案。

答案是(14,3,13)。

我编写的代码不是很好吗? 请告诉我正确的观点......

2 个答案:

答案 0 :(得分:1)

如果你想根据自己的需要调整算法,那么首先要逐字地实现算法总是一个好主意,特别是如果你的伪代码足够详细,可以逐字转换为C代码(对Fortran更是如此,但我离题了)

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

int main (void){
    // type index 1..n
    int index;
    // var
    // x: integer
    int x;
    //i, k, lim: integer
    int i, k, lim;
    // prim: boolean
    bool prim;
    // p: array[index] of integer {p[i] = i'th prime number}
    /*
       We cannot do that directly, we need to know the value of "index" first
    */
    int res;

    res = scanf("%d", &index);
    if(res != 1 || index < 1){
        fprintf(stderr,"Only integral values >= 1, please. Thank you.\n");
        return EXIT_FAILURE;
    }
    /*
       The array from the pseudocode is a one-based array, take care
    */
    int p[index + 1];
    // initialize the whole array with distinguishable values in case of debugging
    for(i = 0;i<index;i++){
       p[i] = -i;
    }
    /*
        Your variables
    */
    int lim_count = 0, k_count = 0;

    // begin
    // p[1] = 2
    p[1] = 2;
    // write(2)
    puts("2");
    // x = 1
    x = 1;
    // lim = 1
    lim = 1;
    // for i:=2 to n do
    for(i = 2;i < index; i++){
       // repeat (until prim)
       do {
          // x = x + 2
          x += 2;
          // if(sqr(p[lim]) <= x) then
          if(p[lim] * p[lim] <= x){
             // lim = lim +1
             lim++;
             lim_count++;
          }
          // k = 2
          k = 2;
          // prim = true
          prim = true;
          // while (prim and (k < lim)) do
          while (prim && (k < lim)){
             // prim = "x is not divisible by p[k]"
             if((x % p[k]) == 0){
                prim = false;
             }
             // k = k + 1
             k++;
             k_count++;
          }
       // (repeat) until prim
       } while(!prim);
       // p[i] := x
       p[i] = x;
       // write(x)
       printf("%d\n",x);
    }
    // end

    printf("x = %d, lim_count =  %d, k_count =  %d \n",x,lim_count,k_count);

    for(i = 0;i<index;i++){
       printf("%d, ",p[i]);
    }
    putchar('\n');

    return EXIT_SUCCESS;
}

它将从2开始打印index - 1个素数。

您现在可以轻松更改它 - 例如:仅打印素数至index而不是index - 1素数。

在你的情况下,所有六个素数的数字最多为13给出

x = 13, lim_count =  2, k_count =  3

与您想要的结果明显不同。

答案 1 :(得分:0)

你的翻译看起来很草率。

for i:= 2 to n do begin

必须转换为:

for (i=2; i<=n; i++)
repeat
    ....
until prim

必须转换为:

do {
    ...
} while (!prim);

while prim...循环里面 repeat...until prim循环。

我留给您将其应用于您的代码并检查所有构造是否已正确翻译。这样做看起来并不太难。

注意:看起来算法使用基于1的数组,而C使用基于0的数组。