|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
ProblemNależy znaleźć n kolejnych liczb pierwszych (ang. primes). Liczba naturalna p jest
liczbą pierwszą (ang. prime number) posiadającą
dokładnie dwa różne podzielniki: 1 i siebie samą. |
Pierwsze, narzucające się podejście do problemu generacji liczb pierwszych jest bardzo prymitywne. Po prostu bierzemy kolejne liczby naturalne poczynając od 2 (1 nie jest pierwsze ponieważ dzieli się tylko przez 1 i brakuje nam drugiego podzielnika). Wybraną liczbę naturalną p próbujemy dzielić przez liczby od 2 do p-1. Jeśli żadna z tych liczb nie jest podzielnikiem p, to liczba p jest pierwsza. Wyprowadzamy ją i w specjalnym liczniku odnotowujemy ten fakt. Gdy licznik osiągnie stan n, kończymy algorytm.
K01: lp ← 0 ; zerujemy licznik liczb pierwszych K02: p ← 2 ; generację rozpoczynamy od 2 K03: Dopóki lp < n: ; pętla generacji liczb pierwszych wykonuj kroki K04…K08 K04: Dla d = 2, 3, …, p-1: ; pętla sprawdzania podzielności wykonuj krok K05 ; p przez d K05: Jeśli p mod d = 0, ; jeśli p dzieli się przez d, idź do kroku K08 ; to nie jest pierwsze K06: Pisz p ; p jest pierwsze K07: lp ← lp+1 ; zwiększamy licznik wygenerowanych ; liczb pierwszych K08: p ← p+1 ; przechodzimy do kolejnej liczby, kandydata K09: Zakończ
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Program w pierwszym wierszu czyta liczbę n i w następnych wierszach wypisuje n kolejnych liczb pierwszych. |
Pascal// Liczby pierwsze
// Data: 15.03.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------
program prg;
var n, lp, p, d : longword;
t : boolean;
begin
readln(n);
lp := 0;
p := 2;
while lp < n do
begin
t := true;
for d := 2 to p-1 do
if p mod d = 0 then
begin
t := false;
break;
end;
if t then
begin
write(p, ' ');
inc(lp);
end;
inc(p);
end;
writeln;
end. |
// Liczby pierwsze
// Data: 15.03.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------
#include <iostream>
using namespace std;
int main()
{
unsigned int n, lp, p, d;
bool t;
cin >> n;
lp = 0;
p = 2;
while(lp < n)
{
t = true;
for(d = 2; d < p; d++)
if(p % d == 0)
{
t = false;
break;
}
if(t)
{
cout << p << " ";
lp++;
}
p++;
}
cout << endl;
return 0;
} |
Basic' Liczby pierwsze
' Data: 15.03.2008
' (C)2020 mgr Jerzy Wałaszek
'---------------------------
Dim As Uinteger n, lp, p, d, t
Input n
lp = 0
p = 2
While lp < n
t = 1
For d = 2 To p-1
If p Mod d = 0 Then
t = 0
Exit For
End If
Next
If t = 1 Then
Print p;" ";
lp += 1
End If
p += 1
Wend
Print
End |
Python (dodatek)# Liczby pierwsze
# Data: 6.02.2024
# (C)2024 mgr Jerzy Wałaszek
# ---------------------------
n = int(input())
lp = 0
p = 2
while lp < n:
t = True
for d in range(2, p):
if p%d == 0:
t = False
break
if t:
print(p, end=" ")
lp += 1
p += 1
print()
|
| Wynik: |
20 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 |
Pierwszy algorytm generowania liczb pierwszych jest bardzo nieefektywny dla
dużych n. Początkowo działa szybko, później wyraźnie zwalnia, aby na
końcu osiągnąć wręcz żółwie tempo pracy. Jest to typowa cecha algorytmów o
klasie złożoności obliczeniowej O(n2) – aby
przekonać się, iż liczba p jest liczbą pierwszą, algorytm musi
wykonać
Jeśli liczba p jest złożona, to rozkłada się na iloczyn czynników pierwszych:
p = d1×d2×…×dk
Czynników tych musi być przynajmniej 2 i muszą one być różne od 1 i p
(dlaczego?). Prosta analiza pokazuje nam, iż w przedziale od pierwiastka
z p do
Drugie ulepszenie będzie polegało na eliminacji niektórych wartości p.
Na przykład jedyną liczbą pierwszą parzystą jest 2. Wszystkie inne są już
nieparzyste. Możemy pójść dalej tym tropem i dokonać dalszych eliminacji. Dwoma
początkowymi liczbami pierwszymi są liczby 2 i 3. Zatem z ciągu dalszych
kandydatów na liczby pierwsze możemy wyeliminować wszystkie wielokrotności liczb
2 i 3, takie jak 6, 8, 9, 10, 12, 14, 15… Liczby te mają postać
Trzecie ulepszenie polega na tym, iż sprawdzamy podzielność nie przez kolejne liczby z przedziału od 2 do pierwiastka z p lecz przez liczby pierwsze wpadające w ten przedział. Po prostu algorytm w miarę znajdowania kolejnych liczb pierwszych umieszcza je w osobnej tablicy i wykorzystuje do testowania podzielności nowych kandydatów na liczbę pierwszą. Wymaga to co prawda tablicy n elementowej, ale opłaci się szybkością eliminacji liczb złożonych. Zwykle tak jest, iż szybkość pracy algorytmu zwiększa się kosztem większego zapotrzebowania na pamięć.
K01: Lp ← 0 ; ustawiamy licznik liczb pierwszych K02: k ← 1 ; oraz zmienne do generacji p = 6k±1 d ← 1 p ← 2 K03: Dopóki Lp < n, ; w pętli znajdujemy kolejne liczby pierwsze wykonuj kroki K04…K16 K04: Jeśli Lp < 3, ; początkowe trzy liczby pierwsze są zadane z góry to p ← p+Lp i idź do kroku K14 K05: p ← 6×k+d ; pozostałe musimy szukać wśród liczb 6k±1 K06: Jeśli d = 1, ; modyfikujemy d i k dla następnej liczby p to idź do kroku K08 K07: d ← 1 i idź do kroku K09 K08: d ← -1 k ← k+1 K09: g ← [sqr(p)] ; granica sprawdzania podzielności p K10: i ← 2 K11: Dopóki tlp[i] ≤ g: wykonuj kroki K12…K13 K12: Jeśli p mod tlp[i] = 0, ; sprawdzamy podzielność p to następny obieg pętli K03 ; przez podzielniki z tlp K13: i ← i+1 ; indeks następnego podzielnika K14 tlp[Lp] ← p ; liczbę pierwszą zapamiętujemy w tlp K15: Pisz p K16: Lp ← Lp+1 K17: Zakończ
|
Uwaga: Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich. |
| Program w pierwszym wierszu czyta liczbę n i w następnych wierszach wypisuje kolejne liczby pierwsze. |
Pascal// Liczby pierwsze
// Data: 15.03.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------
program prg;
type
Tlwarray = array of longword;
var i, k, g, n, Lp, p : longword;
d : integer;
t : boolean;
tlp : Tlwarray;
begin
readln(n);
setlength(tlp, n);
Lp := 0;
k := 1;
d := 1;
p := 2;
while Lp < n do
begin
t := true;
if Lp < 3 then
inc(p, Lp)
else
begin
p := 6*k+d;
if d = 1 then
begin
d := -1; inc(k)
end
else d := 1;
g := round(sqrt(p));
i := 2;
while tlp[i] <= g do
begin
if p mod tlp[i] = 0 then
begin
t := false;
break
end;
inc(i)
end
end;
if t then
begin
tlp[Lp] := p;
write(p, ' ');
inc(Lp)
end
end;
writeln;
SetLength(tlp, 0);
end. |
// Liczby pierwsze
// Data: 15.03.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
unsigned int i, k, g, n, Lp, p, *tlp;
int d;
bool t;
cin >> n;
tlp = new unsigned int [n];
Lp = 0; k = 1; d = 1; p = 2;
while(Lp < n)
{
t = true;
if(Lp < 3) p += Lp;
else
{
p = 6*k+d;
if(d == 1)
{
d = -1; k++;
}
else d = 1;
g = (unsigned int)sqrt(p);
for(i = 2; tlp[i] <= g; i++)
if(!(p % tlp[i]))
{
t = false;
break;
}
}
if(t)
{
tlp[Lp++] = p;
cout << p << " ";
}
}
cout << endl;
delete [] tlp;
return 0;
} |
Basic' Liczby pierwsze
' Data: 15.03.2008
' (C)2020 mgr Jerzy Wałaszek
'----------------------------
Dim As Uinteger i, k, g, n, Lp, p, t
Dim As Integer d
Input n
Dim As Uinteger tlp(n)
Lp = 0: k = 1: d = 1: p = 2
While Lp < n
t = 1
If Lp < 3 Then
p += Lp
Else
p = 6*k+d
If d = 1 Then
d = -1: k += 1
Else
d = 1
End If
g = Cuint(Sqr(p))
i = 2
While tlp(i) <= g
If p Mod tlp(i) = 0 Then
t = 0: Exit While
End If
i += 1
Wend
End If
If t = 1 Then
tlp(Lp) = p
Print p;" ";
Lp += 1
End If
Wend
Print
End |
Python (dodatek)# Liczby pierwsze
# Data: 6.02.2024
# (C)2024 mgr Jerzy Wałaszek
#---------------------------
import math
n = int(input())
tlp = []
lp, k, d, p = 0, 1, 1, 2
while lp < n:
t = True
if lp < 3:
p += p
else:
p = 6*k+d
if d == 1:
d = -1
k += 1
else:
d = 1
g = int(math.sqrt(p))
i = 2
while tlp[i] <= g:
if p % tlp[i] == 0:
t = False
break
i += 1
if t:
tlp.append(p)
print(p, end=" ")
lp += 1
print()
|
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.