IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Jaroslav Kusák:5.2.2021 16:42

Dobrý den, potřeboval bych pomoct s úkolem do školy, a to s vypsáním prvních n-prvočísel (hodnotu n - počet vypsaných prvočísel - si určí uživatel).

Zkusil jsem: Zkoušel jsem si napsat kód nejdříve v C#, kde vše funguje v pořádku, ale při přepsání do Pascalu to vypisuje pouze první dvě prvočísla.

Chci docílit: Potřeboval bych pomoct se syntaxí, nejsem úplně zvyklý na načítání indexů od jedničky, je možné že právě v tomhle je problém. Předem děkuji za každou radu. Přikládám kód v Pascalu.

var i,j,k,l,n,countr : integer;
prvocisla : array[0..20] of integer;

begin
writeln('Zadejte prosím počet prvočísel na vypsání: ');
readln(n);
prvocisla[1] := 2; // na první pozici vždy bude dvojka
k := 3; // nejnižší velikost řady (začínáme na indexu 2)
l := 2; // index prvočísel (začínáme na dvojce, první pozice je obsazena)
countr := 1;

for i := 2 to k do
        begin for j := 1 to l-1 do begin
                if (i mod prvocisla[j] <> 0) then
                        countr := countr + 1; end;
                if (countr = l) then begin
                        prvocisla[l] := i; l:=l+1;  end;
                if (n <> l-1) then
                        k := k + 1;
                countr := 1;
        end;
for i := 1 to n do writeln(prvocisla[i]);
readln;
end.
 
Odpovědět
5.2.2021 16:42
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jaroslav Kusák
DarkCoder:5.2.2021 18:22

Poradím Ti v jiném ohledu. Zadání jasně říká, že máš vypsat prvních n prvočísel. Výpis můžeš provádět za letu, není důvod jakkoli používat pole. Dále použití staticky alokovaného pole není zrovna vhodné, když neznáš počet prvků, které lze do něj uložit, v době překladu.

Nahoru Odpovědět
5.2.2021 18:22
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na Jaroslav Kusák
Matúš Olejník:6.2.2021 12:22

Ahoj, keď chceš len vypisovať prvočísla nemusíš si ich ukladať do poľa ako spomenul aj DarkCoder. Navyše v tvojom poli očakávaš len 20 čísel a nijako nebrániš užívateľovi zadať, že ich chce napr. 100.

Kód čo si poslal je dosť neprehľadný. Pre premenné používaj kľudne aj dlhšie názvy ktoré vystihujú k čomu tá premenná naozaj slúži. Máš tam i,j,k,l,n, okey i, j sa používajú v cykloch ako riadiace premenné, n chápem, že tam pôjde vstup, ale potom k, l premenné netuším na čo presne slúžia.

Rovnako nemusíš šetriť miesto takýmto zápisom

prvocisla[l] := i; l:=l+1;  end;

ľahko sa stratíš alebo prehliadneš čo na tom riadku vlastne robíš. Rovnako keď by si dostal chybu ktorá by ukazovala na tento riadok tak hneď nemusíš vedieť ktorý presne príkaz na tom riadku zlyhal.

Nakoniec len tak pre optimalizáciu, nemusíš kontrolovať párne čísla. Taktiež nemusíš hľadané číslo testovať či je deliteľné bezozvyšku všetkými číslami od 2 po to číslo. Stačí ísť od 2, resp. od 3 keďže párne vynechávaš, po odmocninu testovacieho čísla. Pretože ak by jeden sčítanec bol väčší ako odmocnina z toho testovacieho čísla tak druhý sčítanec musí byť menší ako odmocnina z toho testovaného čísla. A tie sčítance testuješ v cykle ako prvé. Tiež nemusíš v cykle pokračovať ak už si našiel číslo deliteľné bezozvyšku.

var
    i, n, primesCounter, testNumber : integer;
    isPrimeNumber : boolean;

begin
    primesCounter := 1;
    testNumber := 3; //aby som nizsie mohol krajsie "skakat" len po neparnych cislach
    isPrimeNumber := true;

    writeln('Zadejte prosím počet prvočísel na vypsání: ');
    readln(n);

    if(n > 0) then begin
        writeln(2);
    end;

    while primesCounter < n do begin
        //dvojku mozem vynechat lebo parne cisla preskakujem
        i := 3;
        //testujem delitelnost len pre cisla menšie ako odmocnica z testovacieho
        while i <= round(sqrt(testNumber)) do begin
            if(testNumber mod i = 0) then begin
                isPrimeNumber := false;
                //ak je delitelne nemusim pokracovat v cykle lebo uz viem ze nie je prvocislo
                break;
            end;

            i := i + 1;
        end;

        if (isPrimeNumber) then begin
            writeln(testNumber);
            primesCounter:= primesCounter + 1;
        end;

       testNumber := testNumber + 2; //preskocim parne cisla
       isPrimeNumber := true;
    end;

    readln();

end.
Akceptované řešení
+20 Zkušeností
Řešení problému
Nahoru Odpovědět
6.2.2021 12:22
/* I am not sure why this works but it fixes the problem */
Avatar
Odpovídá na Matúš Olejník
Jaroslav Kusák:6.2.2021 18:47

Děkuju moc, za rady i za kód. Našel jsem si něco o algoritmu Eratosthenovo síto, což je v podstatě to, co jste tady popsal, je to mnohem efektivnější (a hlavně to funguje) :-) .

 
Nahoru Odpovědět
6.2.2021 18:47
Avatar
Odpovídá na Matúš Olejník
Jaroslav Kusák:6.2.2021 18:56

No... řekl jsem to špatně, není to to samé, ale princip je podobný.

 
Nahoru Odpovědět
6.2.2021 18:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.