#include
#include
#define MAX 100000
main()
{
int i;
int x;
int range;
int dokad;
int tablica[MAX];
printf("Podaj zakres\n");
scanf("%d",&range);
dokad=floor(sqrt(range));
for (i=1; i<=range; i++) tablica[i]=1;
for (i=2; i<=dokad; i++){
if (tablica[i] != 0){
x = i+i;
while (x<=range){
tablica[x] = 0;
x+=i;
}
}
}
printf("Liczby pierwsze z zakresu od 1 do %d\n\n",range);
for(i=2; i<=range; i++)
if(tablica[i]!=0)
printf("%6.d ",i);
printf("\nf(n)=%f\n",range/log(range));
}
Nie wiem jednak jak sprawić by dodatkowo wyliczał ile jest tych liczb pierwszych w przedziale.
Nie wiem też jak sprawić by sprawdzał liczby pierwsze dla zakresu liczb z 1000000.
Przy 100000 program się zawiesza i wyświetla się błąd:
Tablica jest indeksowana wartościami 0 … MAX-1. Ty natomiast w warunkach pętli masz <=, czyli teoretycznie może wyjść poza tablicę. Jeśli sito ma obejmować liczby od 0 do N, tablica powinna mieć N+1 elementów.
Dla dużych tablic użyj raczej dynamicznej alokacji - malloc, free.
Najpierw wszystkie liczby oznaczasz jako pierwsze, a potem wykreślasz złożone. Czyli możesz użyć licznika, zainicjować go na szerokość przedziału, a potem w miejscu gdzie oznaczasz liczby jako złożone, dekrementować ten licznik.
Może mnie ktoś uświadomić po co tutaj w ogóle jakakolwiek tablica?
Na moje oko wystarczy jedna funkcja sprawdzająca czy liczba jest pierwsza, oraz druga funkcja przyjmująca w argumentach zakres liczb do sprawdzenia i licząca ilość pierwszych przy użyciu pierwszej funkcji.
ptasior , sprawdziłbym jej parzystość, a następnie podzielność przez liczby nieparzyste począwszy od 3 do pierwiastka z tej liczby. Żadna tablica tu nie jest do niczego potrzebna.
I myślisz że byłaby to wydajna metoda? Po jaką cholerę używać tak naiwnej metody, skoro można skorzystać z sita eratostenesa i na koniec zliczyć tylko 0 występujące w tablicy?
Wbrew pozorom test naiwny po przedziale nie musi być bardzo wolny. Dla argumentów do miliona, bo chyba o takim ograniczeniu wspominał autor wątku, powinno i tak być wystarczająco szybko. Z ciekawości sprawdziłem u siebie i różnica to mniej więcej 0.2s dla naiwnego testu i 0.02s dla sita.
Spytałeś, jak chcę sprawdzić nie używając tablicy, więc Ci odpowiedziałem. Tablica jest całkowicie zbędna w tym procesie i to jest fakt. Można skorzystać z sita, w zakresie do miliona będzie działało nawet nieźle, ale z miliardem już chyba będzie problem. A jak jest z jego wydajnością przy testowaniu pojedynczych liczb?
– Dodane 09.01.2012 (Pn) 0:39 –
Niektórzy za to potrafią go bardzo wolno zaimplementować.
Zależnie ile ma pamięci ale do miliona (raczej), można sobie pozwolić na stablicowanie i podanie odpowiedzi w czasie O(1).
Ewentualnie stablicować nie wszystkie liczby, tylko liczby pierwsze i podać odpwiedź w czasie O(lgn) też byłoby całkiem nieźle, liczb pierwszych w tym zakresie nie ma b. dużo.