keser
keser

Reputation: 2642

Sieve of Eratosthenes - C language implementation

I am missing something but I can't find what it is. I have also been given a input2.c file and it has a print_prim function which I am not allowed to change.

For n=10 it is always printing

4, 5, 7, 9, 

I know there is an i+2 in print_prim function but I can't solve it. Again, I am not allowed to change print_prim function. Can anyone see what am i missing?


main.c


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

int main() {
    int n = lese_int();
    int laenge = n-1; 
    int *array;  
    array = malloc(sizeof(int) * laenge);  
    for (int i = 2; i <= n; i++) {
        array[i] = 1;  
    }

    for(int i=0;i<=n;i++) {
        if(array[i] == 1){
            for(int j = i ; i*j <= n ; j++){
                array[i*j] = 0;
            }   
        } 
    }
    print_prim(array, laenge);
    free(array); 
    return 0;
}

print_prim function

void print_prim(int *array, int laenge) {
    for (int i=0; i<laenge; i++) {
        if (array[i] == 1) {
            printf("%d, ", i+2);
        }
    }
    printf("\n");
}

Upvotes: 3

Views: 374

Answers (2)

Mukul Gupta
Mukul Gupta

Reputation: 2425

All you need is a normal sieve shifted by 2 elements.

int main() {
  int n;
  scanf("%d", &n);

  int *a = (int*)malloc(sizeof(int) * (n - 1));
  for (int i = 0; i < n - 1; i++ ) a[i] = 1;

  for (int i = 2; i*i <= n; i++) {
    if (a[i-2] == 1) {
      for (int j = i * i; j <= n; j+=i ) a[j-2] = 0;
    }
  }

  print_prim(a, n - 1);

  free(a);
  return 0;
}

Explanation:

  • Allocate n-1 elements to represent numbers from 2 to n inclusive.
  • Initialize all elements with 1. Why? Because looking at print_prim, it prints values which are equal to 1. So, all our primes need to be shifted by 2 and its value should be 1.
  • Starting with 2, we mark all multiples of prime numbers as 0. The ones that stay 1 are primes. See https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes for details.
  • Since, print_prim is shifted by 2, we need to pass n-1 as the second argument for inclusive printing.

Upvotes: 2

Jos&#233; Manuel Ramos
Jos&#233; Manuel Ramos

Reputation: 355

Reformatting the code

A common step to help you is to format to us

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

int main ( void )
{
  int n = lese_int();
  int laenge = n - 1; 
  int *array;

  array = malloc( sizeof( int ) * laenge );

  for ( int i = 2; i <= n; i++ )
  {
    array[i] = 1;
  }

  for ( int i = 0; i <= n; i++ )
  {
    if ( array[i] == 1 )
    {
      for ( int j = i; i * j <= n; j++ )
      {
        array[ i * j ] = 0;
      }
    }
  }

  for ( int i = 0; i < laenge; i++ )
  {
    printf( "%d, ", array[i] );
  }

  printf( "\n" );
  print_prim( array, laenge );
  free( array );
  return ( 0 );
}

And the print_prim function is:

void print_prim ( int *array, int laenge )
{
  for ( int i = 0; i < laenge; i++ )
  {
    if ( array[i] == 1 )
    {
      printf( "%d, ", i + 2 );
    }
  }
  printf( "\n" );
}

Note: this style is personal and it's not intended to make a religion-like flamming wars using spacing like me, or curl braces down.


Errors found when reading:

You use C99. Take that into account prior to change something. (know your language)

You make a memory allocation of n - 1 elements, but you try to access from the element 2 to the element n, both including, in the first for loop. (know how memory allocation works)

Arrays start at zero (insert joke), so, you can't reach the element n nor the element n - 1.

print_prim only prints the value plus 2 of the array element that contains 1. In other words: try to locate all the positions in the array which contains 1, and increment that position with 2. (know how to read-debugging)


I reccomend you to study how the language works instead of trial'n'error based programming. It will save you lot's of hours and you will learn more.

Upvotes: -1

Related Questions