Liczby pierwsze - sito Eratostenesa

Podobne dokumenty
Liczby pierwsze - generacja liczb pierwszych

Przeliczanie na zapis stałoprzecinkowy

Całkowanie numeryczne - metoda prostokątów

Całkowanie numeryczne - metoda Simpsona

Miejsca zerowe funkcji - Metoda połowienia

Miejsca zerowe funkcji - Metoda Newtona

Wyszukiwanie największej spośród czterech liczb. Przykładowe rozwiązanie

binit - binary digit, bigit - binary digit

Sortowanie stogowe Heap Sort

WYKŁAD 3 (13 MARZEC 2014) LICZBY CAŁKOWITE I RZECZYWISTE. Bartosz Łakomy i Dariusz Dobiesz

Ilość cyfr liczby naturalnej

Liczby całkowite i rzeczywiste

Liczby pierwsze - algorytm RSA

Palindromy. Przykładowe rozwiązanie

Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka

Sortowanie przez scalanie Merge Sort

Programowanie komputerowe. Zajęcia 1

(3 kwiecień 2014) Marika Pankowska Kamila Pietrzak

Podstawy Programowania

wagi cyfry pozycje

Wstęp do programowania

Funkcje i instrukcje języka JavaScript

Pytania sprawdzające wiedzę z programowania C++

Ćwiczenie 3 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

8. Wektory. Przykłady Napisz program, który pobierze od użytkownika 10 liczb, a następnie wypisze je w kolejności odwrotnej niż podana.

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

INFORMATYKA Z MERMIDONEM. Programowanie. Moduł 5 / Notatki

1 Podstawy c++ w pigułce.

Podstawy Programowania Podstawowa składnia języka C++

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Wstęp do Informatyki

Problem W przedziale całkowitym <a,b> wyszukaj wszystkie liczby parzyste.

do instrukcja while (wyrażenie);

Kontrola przebiegu programu

Operacje arytmetyczne w systemie dwójkowym

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

tablica: dane_liczbowe

Podstawy programowania. Wykład: 4. Instrukcje sterujące, operatory. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

MACIERZE. Sobiesiak Łukasz Wilczyńska Małgorzata

Algorytmy i struktury danych

Wstęp do informatyki- wykład 7

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Programowanie i struktury danych

Część 4 życie programu

Wstęp do programowania

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 5 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 41

r. Tablice podstawowe operacje na tablicach

Podstawowe algorytmy i ich implementacje w C. Wykład 9

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Tablice. Monika Wrzosek (IM UG) Podstawy Programowania 96 / 119

Programowanie. programowania. Klasa 3 Lekcja 9 PASCAL & C++

Konstrukcje warunkowe Pętle

2.8. Algorytmy, schematy, programy

Programowanie proceduralne w języku C++ Pętle, tablice

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Język programowania PASCAL

Anna Sobocińska Sylwia Piwońska

Programowanie - wykład 4

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

Pętle. Dodał Administrator niedziela, 14 marzec :27

JAVAScript w dokumentach HTML (2)

Instrukcje cykliczne (pętle) WHILE...END WHILE

Podstawy programowania obiektowego

Wstęp do programowania

Podstawy programowania skrót z wykładów:

Informatyka dla klas I wykresy funkcji

Programowanie w VB Proste algorytmy sortowania

Programowanie komputerowe. Zajęcia 4

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

Wstęp do informatyki- wykład 8 Pętla while, do while,for -pętla w pętli- przykłady Operator rzutowania Manipulatory

Zmienne i struktury dynamiczne

Algorytmika i programowanie. Wykład 2 inż. Barbara Fryc Wyższa Szkoła Informatyki i Zarządzania w Rzeszowie

Wstęp do programowania

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Wrocław, Wstęp do informatyki i programowania: liczby pierwsze. Wydział Matematyki Politechniki Wrocławskiej.

Lekcja : Tablice + pętle

7. Pętle for. Przykłady

Nazwa implementacji: Nauka języka Python pętla for. Autor: Piotr Fiorek

JAVAScript w dokumentach HTML - przypomnienie

I - Microsoft Visual Studio C++

Informatyka 1. Wyrażenia i instrukcje, złożoność obliczeniowa

Transponowanie macierzy Mnożenie macierzy Potęgowanie macierzy Wyznacznik macierzy

Struktura pliku projektu Console Application

Wydział Zarządzania AGH. Katedra Informatyki Stosowanej. Pętle. Programowanie komputerowe

Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Podstawy programowania w języku Visual Basic dla Aplikacji (VBA)

Programowanie - instrukcje sterujące

Wstęp do informatyki- wykład 6

3. Instrukcje warunkowe

Zaawansowane algorytmy i struktury danych

Podstawy programowania 2. Temat: Drzewa binarne. Przygotował: mgr inż. Tomasz Michno

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Opis zagadnieo 1-3. Iteracja, rekurencja i ich realizacja

Wykład 03 JavaScript. Michał Drabik

Podstawy algorytmiki i programowania - wykład 6 Sortowanie- algorytmy

Algorytm i złożoność obliczeniowa algorytmu

WHILE (wyrażenie) instrukcja;

1 Podstawy c++ w pigułce.

Maxima i Visual Basic w Excelu

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Transkrypt:

Artykuł pobrano ze strony eioba.pl Liczby pierwsze - sito Eratostenesa Już w czasach starożytnych znano metodę opisaną przez greckiego uczonego Eratostenesa z Cyreny. Podszedł on do rozwiązania od drugiej strony. Eratostenes (Eratostenes z Cyreny) urodził się w 276 roku p.n.e, zmarł w 194 p.n.e. Był greckim uczonym, filozofem matematykiem,, astronomem, geografem oraz poetą. Jego osiągnięcia to oszacowanie średnicy Ziemi raz odległości od Słońca i Księżyca, pomiar kąta nachylenia ekliptyki do równika niebieskiego, propozycja wprowadzenia roku przestępnego, metoda znajdowania liczb pierwszych nazwana na jego cześć sitem Eratostenesa. Kierował biblioteką w Aleksandrii. W poprzednim rozdziale opisaliśmy znajdowanie liczb pierwszych na podstawie ich definicji, tj. sprawdzając podzielność przez liczby mniejsze. Sposób ten nie jest najefektywniejszą metodą wyszukiwania liczb pierwszych - musimy wykonywać określoną ilość czasochłonnych dzieleń, tym większą, im większą wartość ma badana liczba. W czasach starożytnych znano lepszą metodę opisaną przez greckiego uczonego Eratostenesa z Cyreny. Podszedł on do rozwiązania od drugiej strony - zamiast sprawdzać podzielność kolejnych liczb naturalnych przez znalezione liczby pierwsze, zaproponował wyrzucanie ze zbioru liczb naturalnych wielokrotności kolejnych liczb, które nie zostały wcześniej wyrzucone. To, co zostanie, będzie zbiorem liczb pierwszych, które nie posiadają innych podzielników jak 1 i same siebie. Metoda ta została nazwana sitem Eratostenesa i jest najszybszą metodą wyszukiwania liczb pierwszych w ograniczonym zbiorze. Zobaczmy jak działa sito Eratostenesa. Spróbujmy wg tej metody odszukać wszystkie liczby pierwsze w zbiorze 20 początkowych liczb naturalnych. Generacja liczb pierwszych przy pomocy sita Eratostenesa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Oto początkowy zbiór liczb. Najpierw usuniemy z niego liczbę 1 - nie jest to liczba pierwsza, ponieważ nie posiada dokładnie dwóch różnych podzielników.

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Bierzemy pierwszą liczbę 2 i usuwamy ze zbioru wszystkie jej wielokrotności. W ten sposób pozbyliśmy się liczb parzystych. Zauważ iż obliczanie wielokrotności nie wymaga mnożenia - wystarczy dodawać daną liczbę. 2 3 5 7 9 11 13 15 17 19 Następną wolną liczbą jest 3. Usuwamy ze zbioru wszystkie wielokrotności liczby 3. Pozostaną więc liczby niepodzielne przez 2 i przez 3. 2 3 5 7 11 13 17 19 Wykonane - w zbiorze pozostały same liczby pierwsze. Przed opisem algorytmu musimy zdecydować, w jaki sposób będziemy reprezentować w pamięci komputera zbiór liczb. Najprostszym rozwiązaniem wydaje się być tablica wartości logicznych. Liczbę określa indeks elementu tablicy. Wartość elementu określa z kolei, czy dana liczba jest w zbiorze czy też jej tam nie ma. Na przykład: t[5] - element ten odnosi się do liczby 5. t[5] = true - liczba 5 jest w zbiorze. t[5] = false - liczba 5 została ze zbioru wyrzucona. Na początku wpiszemy do każdego elementu wartość true - wszystkie liczby będą w zbiorze. Następnie w elementach, których indeks jest równy wartości wyrzucanych liczb, umieścimy false. Na koniec przeglądniemy całą tablicę i wypiszemy te indeksy, dla których wskazywane elementy zawierają wciąż wartość true. Dane wejściowe g- górny kres przedziału, w którym poszukujemy liczb pierwszych, g N Dane wyjściowe Kolejne liczby pierwsze zawarte w przedziale od 2 do g. Zmienne pomocnicze i - służy do sterowania pętlami iteracyjnymi, i N - tablica logiczna odwzorowująca zbiór liczbowy. Indeksy elementów przebiegają wartości od 2 do t[ ] g w - służy do tworzenia kolejnych wielokrotności, w N krok 1:Czytaj g krok 2:Dla i = 2,3,...,g wykonuj t[i] true krok 3:Dla i = 2,3,...,g wykonuj kroki 4...7 krok 4: w 2i krok 5: Dopóki w g wykonuj kroki 6,7. Inaczej wykonaj następny obieg pętli z kroku 3. krok 6: t[w] false krok 7: w w + i krok 8:Dla i = 2,3,...,g jeżeli t[i] = true, to pisz i krok 9:Zakończ algorytm

Prezentowany algorytm Sita Eratostenesa jest maksymalnie uproszczony. Na początku odczytujemy górny kres przedziału, w którym będziemy wyznaczać liczby pierwsze umieszczając go w zmiennej g. Następnie wykonywane są kolejno trzy pętle iteracyjne: Pętla nr 1: - inicjalizacja ustawia wszystkie elementy tablicy t[ ] na true. Zwróć uwagę, iż tablica jest ustawiana od elementu o indeksie 2. Zgodnie z tym, co powiedzieliśmy wyżej, tablica t[ ] odzwierciedla zbiór liczb naturalnych, w którym wartościami kolejnych liczb są indeksy elementów, natomiast zawartość tych elementów określa, czy reprezentowane przez nie liczby są (true) lub nie są (false) obecne w zbiorze. Pętla nr 2: - eliminacja usuwa ze zbioru wszystkie wielokrotności kolejnych liczb. Dokonujemy tego bez żadnych sprawdzeń, co oczywiście nie jest zbytnio efektywne, ale za to bardzo proste. W zmiennej w tworzymy pierwszą wielokrotność i-tej liczby. Następnie wszystkie elementy o indeksach równych kolejnym wielokrotnościom ustawiamy na false. Po zakończeniu pętli 2 w tablicy t[ ] wartość true pozostaje jedynie w elementach, których indeksy są liczbami pierwszymi. Pętla nr 3: - prezentacja przegląda kolejne elementy tablicy t[ ] i jeśli mają one wartość true, wyświetla ich indeks. Po wykonaniu tej pętli w oknie konsoli otrzymamy wszystkie liczby pierwsze zawarte w przedziale od 2 do g. Wydruk z uruchomionego programu Wyszukiwanie liczb pierwszych sitem Eratostenesa ------------------------------------------------ (C)2005 mgr Jerzy Wałaszek I LO w Tarnowie Podaj granicę = 500 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 Koniec, naciśnij klawisz ENTER... Microsoft Visual Basic 2005 Express Edition

Borland Delphi 7.0 Personal Edition // Sito Eratostenesa //============================ // (C)2004 mgr Jerzy Wałaszek // I LO w Tarnowie //---------------------------- program Erato; $APPTYPE CONSOLE const MAX_LP = 10000000; // maksymalna długość zbioru t var : array[2..max_lp] of boolean; i,w,g : cardinal; begin writeln('wyszukiwanie liczb pierwszych sitem Eratostenesa'); writeln('------------------------------------------------'); writeln('(c)2004 mgr Jerzy Walaszek I LO w Tarnowie'); writeln; write('podaj granice = '); readln(g); writeln; if g > MAX_LP then writeln('granica zbyt wielka') else begin for i := 2 to g do t[i] := true; for i := 2 to g do begin w := i + i; while w <= g do begin t[w] := false; w := w + i; end; end; for i := 2 to g do if t[i] then write(i : 8); writeln; end; writeln; writeln('koniec, nacisnij klawisz ENTER...'); readln; end.

Borland C++ Builder 6.0 Personal Edition // Sito Eratostenesa //============================ // (C)2004 mgr Jerzy Wałaszek // I LO w Tarnowie //---------------------------- #include <iostream> #include <iomanip> using namespace std; main() const unsigned MAX_LP = 1000000; // maksymalna długość zbioru bool t[max_lp + 1]; unsigned i,w,g; char s[1]; cout << "Wyszukiwanie liczb pierwszych sitem Eratostenesan" "------------------------------------------------n" "(C)2004 mgr Jerzy Walaszek I LO w Tarnowienn" "Podaj granice = "; cin >> g; cout << endl; if(g > MAX_LP) cout << "Granica zbyt wielkan"; else for(i = 2; i <= g; i++) t[i] = true; for(i = 2; i <= g; i++) w = i + i; while(w <= g) t[w] = false; w += i; for(i = 2; i <= g; i++) if(t[i]) cout << setw(8) << i; cout << endl; cout << "nnklawisz Enter = KONIEC"; cin.getline(s,1); cin.getline(s,1);

Microsoft Visual Basic 2005 Express Edition ' Sito Eratostenesa '============================ ' (C)2005 mgr Jerzy Wałaszek ' I LO w Tarnowie '---------------------------- Option Explicit On Module Module1 Sub main() Const MAX_LP = 10000000 ' maksymalna długość zbioru Dim t(max_lp) As Byte Dim i, w, g As UInteger Console.WriteLine("Wyszukiwanie liczb pierwszych sitem Eratostenesa") Console.WriteLine("------------------------------------------------") Console.WriteLine("(C)2005 mgr Jerzy Wałaszek I LO w Tarnowie") Console.WriteLine() Console.Write("Podaj granicę = ") g = Val(Console.ReadLine) Console.WriteLine() If g > MAX_LP Then Console.WriteLine("Granica zbyt wielka") Else For i = 2 To g : t(i) = 1 : Next For i = 2 To g w = i + i While w <= g t(w) = w += i End While Next For i = 2 To g If t(i) > Then Console.Write("0,8", i) Next Console.WriteLine() End If Console.WriteLine() Console.WriteLine("Koniec, naciśnij klawisz ENTER...") Console.ReadLine() End Sub End Module

Python # -*- coding: cp1250 -*- # Sito Eratostenesa #============================ # (C)2005 mgr Jerzy Wałaszek # I LO w Tarnowie #---------------------------- print "Wyszukiwanie liczb pierwszych sitem Eratostenesa" print "------------------------------------------------" print "(C)2005 mgr Jerzy Walaszek I LO w Tarnowie" print g = int(raw_input("podaj granice = ")) print t = range(g + 1) for i in range(2, g + 1): w = i + i while w <= g: t[w] = w += i for i in range(2, g + 1): if t[i]: print "%7d" % i, print print raw_input("koniec, nacisnij klawisz ENTER...")

JavaScript <html> <head> </head> <body> <div align="center"> <form name="frmerato" style="border: 1px outset #FF9933; padding-left: 4px; padding-right: 4px; padding-top: 1px; padding-bottom: 1px; background-color: #FFCC66"> <h3 style="text-align: center"> Sito Eratostenesa </h3> <p style="text-align: center"> (C)2004 mgr Jerzy Wałaszek - I LO w Tarnowie </p> <hr> <p style="text-align: center"> Podaj górną granicę zbioru </p> <p style="text-align: center"> <input type="text" name="t1" size="20" value="100"> </p> <p style="text-align: center"> <input type="button" value="szukaj" name="b1" onclick="main()"> </p> <p id="data_out" style="text-align: center">...</p> </form> <script language=javascript> // Sito Eratostenesa //============================ // (C)2004 mgr Jerzy Wałaszek // I LO w Tarnowie //---------------------------- function main() var t = new Array(); var i,w,g,s; g = parseint(document.frmerato.t1.value); if(isnan(g)) s = "<font color=red><b>złe DANE</b></font>"; else for(i = 2; i <= g; i++) t[i] = true; for(i = 2; i <= g; i++) w = i + i; while(w <= g) t[w] = false; w += i; s = ""; for(i = 2; i <= g; i++) if(t[i]) s += i + " "; document.getelementbyid("data_out").innerhtml = s; </script> </div> </body> </html>

Poniższe, przykładowe programy są praktyczną realizacją omawianego w tym rozdziale algorytmu. Zapewne można je napisać bardziej efektywnie. To już twoje zadanie. Dokładny opis stosowanych środowisk programowania znajdziesz we wstępie. Programy przed opublikowaniem w serwisie edukacyjnym zostały dokładnie przetestowane. Jeśli jednak znajdziesz jakąś usterkę (co zawsze może się zdarzyć), to prześlij o niej informację do autora. Pozwoli to ulepszyć nasze artykuły. Będziemy Ci za to wdzięczni. W algorytmie wyszukiwania liczb pierwszych metodą Sita Eratostenesa nie występuje nigdzie potrzeba dzielenia. Wyznaczając wielokrotności wykonujemy jedynie proste dodawanie, które komputer realizuje bardzo szybko. Z tego powodu prezentowany algorytm czasowo jest najszybszym algorytmem rozwiązującym zadanie wyszukiwania liczb pierwszych. Dla celów badawczych przyjmijmy za operację dominującą wyrzucanie ze zbioru wielokrotności kolejnych liczb. Operacja taka składa się z wyznaczenia wartości tej wielokrotności oraz wstawienia do elementu tablicy (o indeksie równym wielokrotności) wartości logicznej false. W tym celu program należy wyposażyć w odpowiedni licznik. Wykonanie tego zadania, z uwagi na jego prostotę, pozostawiam ambitnym czytelnikom. W poniższej tablicy zebraliśmy rezultaty pracy takiego programu. Wyniki badania ilości wykonanych operacji wyrzucania liczb Zakres poszukiwania Ilość liczb pierwszych operacji wyrzucania Wzrost 2...10 8-2...100 283 35,375 2...1000 5070 17,915 2...10000 73669 14,530 2...100000 966751 13,123 2...1000000 11970035 12,382 2...10000000 142725365 11,924 2...100000000 1657511569 11,613 W pierwszej kolumnie mamy przeszukiwany przez algorytm zakres liczb naturalnych. Zakres przyrasta 10 razy. Druga kolumna zawiera ilość operacji wyrzucania liczby ze zbioru, którą wykonał algorytm Sita Eratostenesa. W trzeciej kolumnie liczymy wzrost operacji wyrzucania przy rozszerzeniu zakresu poszukiwań. Wzrost ten jest liczony jako iloraz liczby operacji z bieżącego wiersza przez liczbę operacji z wiersza poprzedniego. Na podstawie danych zebranych w tej tabelce postaraj się odpowiedzieć na następujące pytania:

1. Do jakiej liczby zmierza wzrost ilości operacji wyrzucania przy 10 krotnym wzroście zakresu poszukiwań liczb pierwszych? 2. Jaką klasę czasowej złożoności obliczeniowej posiada ten algorytm? 3. Uzasadnij swój wybór klasy złożoności obliczeniowej na podstawie analizy działania algorytmu. 4. Dlaczego przyrost stabilizuje się dopiero dla dużych zakresów? 5. Jaki wniosek można wysunąć na temat statystycznego rozkładu częstości występowania liczb pierwszych? Dokument ten rozpowszechniany jest zgodnie z zasadami licencji GNU Free Documentation License. Autor: mgr Jerzy Wałaszek Przedruk ze strony: http://www.i-lo.tarnow.pl/edu/inf/alg/primes/index.html Artykuł pobrano ze strony eioba.pl