ebooksgratis.com

See also ebooksgratis.com: no banners, no cookies, totally FREE.

CLASSICISTRANIERI HOME PAGE - YOUTUBE CHANNEL
Privacy Policy Cookie Policy Terms and Conditions
Eratosthenovo síto - Wikipedie, otevřená encyklopedie

Eratosthenovo síto

Z Wikipedie, otevřené encyklopedie

Eratosthenovo síto je jednoduchý algoritmus pro nalezení všech prvočísel menších než zadaná horní mez. Je pojmenován po řeckém matematikovi Eratosthenovi z Kyrény, který žil v letech 276194 př. n. l.

Algoritmus funguje „prosíváním“ seznamu čísel – na počátku seznam obsahuje všechna čísla v daném rozsahu (2, 3, 4, …, zadané maximum). Poté se opakovaně první číslo ze seznamu vyjme, toto číslo je prvočíslem; ze seznamu se pak odstraní všechny násobky tohoto čísla (což jsou čísla složená). Tak se pokračuje do doby, než je ze seznamu odstraněno poslední číslo (nebo ve chvíli, kdy je jako prvočíslo označeno číslo vyšší než odmocnina nejvyššího čísla – v takové chvíli už všechna zbývající čísla jsou nutně prvočísly). Časová složitost tohoto algoritmu je O(N*log(log N)), kde N je horní mez rozsahu.

Obsah

[editovat] Příklad

Pro nalezení prvočísel mezi prvními 20 čísly:

Krok 1: Seznam obsahuje všechna čísla v rozsahu 2–20:

Seznam: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Krok 2: Odebereme první číslo ze seznamu (2) a označíme ho jako prvočíslo:

Známá prvočísla: 2
Seznam: 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Krok 3: Odebereme ze seznamu všechny násobky právě odebraného prvočísla (4, 6, 8, 10, …):

Známá prvočísla: 2
Seznam: 3 5 7 9 11 13 15 17 19

Krok 4: Pokračujeme opět krokem 2, dokud zbývají nějaká čísla (první číslo v seznamu a také prvočíslo je tentokrát 3):

Známá prvočísla: 2 3
Seznam: 5 7 11 13 17 19

Po dalším opakování:

Známá prvočísla: 2 3 5
Seznam: 7 11 13 17 19

5 je vyšší než √19, takže zbývají už jen prvočísla. (Kdyby ještě existovalo v seznamu číslo X, které je součinem dvou celých čísel A·B, musel by první činitel A být menší než √X a druhý činitel B by musel být větší než √X. Všechny násobky celých čísel menších než √20 jsou již ale ze seznamu odebrány, včetně X. Tím pádem se již v seznamu nenachází žádné číslo, které lze rozložit na součin.)

Výsledný seznam prvočísel v rozsahu 2–20: 2, 3, 5, 7, 11, 13, 17, 19.

[editovat] Zdrojový kód v jazyce Pascal

program ErSito;
 const
   MaxN = 20;
 var
   Pole: array [2 .. MaxN] of boolean;
   i, j: integer;
 begin
   {inicializace: nejprve předpokládáme, že vše jsou prvočísla}
   for i := 2 to MaxN do 
     Pole[i] := true;
   i := 1;
   repeat
     i := i + 1;
     {najdeme prvni cislo, u kterého je true}
     while (i<MaxN) and (not Pole[i]) do i := i + 1;
     {optimalizace: nemá smysl hledat násobky nižších čísel označené dříve}
     j := i;
     {najdeme všechny násobky daného prvočísla, které tudíž nejsou prvočísla}
     while j*i<=MaxN do
        begin
          Pole[j*i] := false;
          j := j + 1;
        end;
   until i>=sqrt(MaxN); {optimalizace: stačí hledat pouze po odmocninu z MaxN}
   {výpis prvočísel}
   for i := 2 to MaxN do
     if Pole[i] then
       Writeln(i);
 end.

[editovat] Zdrojový kód v jazyce Java

int MaxN = 1024;        
  boolean[] Pole = new boolean[MaxN+1];
  int i,j;
  for (i=2;i<(MaxN+1);i++) { /* Inicializace pole (vse jsou prvocisla a postupne budem vyrazovat) */
    Pole[i] = true; 
  }
  i=2;
  while (i*i <= MaxN) { /* dokud mocnina prvniho cisla na seznamu je mensi nez nejvetsi */
    if (Pole[i]){       /* pokud je i stale na seznamu (nezkoumej nasobky 4, kdyz jsme uz vyhodili nasobky 2 */
      j=2;              /* j bude novy nasobek */
      while (i*j <= MaxN) {
        Pole[j*i] = false; /* cislo slozene */
        j++;
      }         
    } 
    i++;
  }

[editovat] Zdrojový kód v jazyce C++

#include <iostream>
#include <set>
using namespace std;
 
int main()
{
 
   int max;
   cout << "Zadejte cislo do ktereho chcete vypsat prvocisla" << endl;
   cin >> max;
 
   set<int> sito, prvocisla;
   set<int>::iterator p;
   int dalsi, nasobek;
 
   for (int i = 2; i <= max; i++)
      sito.insert(i);
 
   dalsi = 2;
   while (!sito.empty())
   {
      while (sito.count(dalsi) == 0) dalsi++;
      prvocisla.insert(dalsi);
      nasobek = dalsi;
      while (nasobek <= max)
      {
         sito.erase(nasobek);
         nasobek += dalsi;
      }
   }
 
   for (p = prvocisla.begin(); p != prvocisla.end(); p++)
      cout << *p << ' ';
   cout << endl;
}

[editovat] Zdrojový kód v jazyce Python

MaxN = 1024                                              #horni hranice seznamu cisel
SeznamN = range(2,MaxN+1)                                #vytvoreni seznamu cisel v rozpeti <2,1024>
Prvocisla = []                                           #vytvoreni (prozatim) prazdneho seznam prvocisel
while SeznamN[0]**2 <= SeznamN[-1]:                      #Dokud bude ctverec prvniho prvku SeznamuN mensi nebo roven poslednimu
                                                         #prvku SeznamuN, vykonej:
    Prvocisla.append(SeznamN[0])                         #    1)K seznamu Prvocisla pripoj prvni cislo ze SeznamuN
    Nasobky = range(SeznamN[0],SeznamN[-1]+1,SeznamN[0]) #    2)Vytvor seznam nasobku naposledy pripojeneho Prvocisla
    for k in Nasobky:                                    #    3)Pro kazde cislo "k" v seznamu Nasobky:
        if k in SeznamN:                                 #        1)Pouze pokud se k naleza v SeznamuN:
            SeznamN.remove(k)                            #            1)Odstran cislo/nasobek k ze SeznamuN;kod se opakuje od 4 radku
                                                         #Prvni cislo v seznamu je vetsi jak odmocnina z cisla posledniho a tedy
Prvocisla.extend(SeznamN)                                #zbyla cisla jsou prvocisla. Extend je podobné k append.
print Prvocisla                                          #Zobraz vysledek!

[editovat] Zdrojový kód v jazyce PHP

function erPrimes($max)
{
        $numbers = range(2,$max,1); //inicializuji si pole cisel od 2 do $max po jedne
        $primes = array(); // inicializace vystupniho pole
        while (list($key,$value) = each($numbers)) { // nactu si dalsi cislo z pole
                if ($value) { // zjistim jestli cislo uz neni vynulovane
                        for ($i=1;($exp = $value*$i) < $max;$i++) { // vynuluju vsechny nasobky aktualniho cisla
                                $numbers[$exp] = null;
                        }
                        $primes[] = $value; // pridam si zjistene prvocislo do vystupu
                }
        }
        return $primes;
}

[editovat] Externí odkazy


aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -