siemka,
po przeczytaniu treści zadania wydało mi się, że komukolwiek, kto zadawał to zadanko, chodziło o użycie algorytmu Sita Eratostenesa.
Wasze rozwiązania są dobre - ale widzę możliwość kilku usprawnień: jeśli chcemy sprawdzić pierwszość liczby n, wystarczy sprawdzić, czy dzieli się bez reszty (mod) przez liczby z zakresu 2..ceil(sqrt(n)) (funkcja ceil zaokrągla do góry- aby jej użyć należy włączyć bibliotekę math przed zasadniczą częścią programu:
Kopiuj
uses math;
var
//zmienne
begin
//program
end.
sqrt - wiadomo, pierwiastek.)
ja to zadanie zrobiłbym tak:
- na pewno jest jakieś ograniczenie przedziałów. tak więc za pomocą sita eratostenesa wyznaczam wszystkie liczby pierwsze od 2 do górnego ograniczenia. konstruuję tablicę booleanów, od 2 do górnego ograniczenia, która dla zadanej liczby zwróci TRUE jeśli liczba jest pierwsza, i false, jeśli złożona. na początku działania algorytmu założymy, że wszystkie liczby w tablicy mają wartość TRUE, i będziemy je eliminować
Sito Eratostenesa działa mniej więcej tak:
- zaczynasz od liczby 2. wiesz, że jest to liczba pierwsza. każda wielokrotność dwójki (4,6,8,10...) na pewno nie jest liczbą pierwszą, tak więc dla każdej wielokrotności dwójki, w tablicy booleanów ustawiasz FALSE
- potem bierzesz kolejną liczbę, której nie wykreśliłaś. jest na pewno liczbą pierwszą - gdyby była złożona, zostałaby wykreślona podczas wcześniejszego działania programu. po dwójce będzie to liczba 3 - zostawiasz jej wartość true, i wykreślasz z tablicy jej wielokrotności.
- bierzesz kolejną liczbę, która nie została wykreślona. liczba 4 już została wykluczona (przy wykreślaniu wielokrotności dwójek), więc bierzesz 5, i wykreślasz wielokrotności.
- i tak dalej
potem, żeby Twoje zadanie dawało dobre wyniki, zrobisz tak:
Kopiuj
program l_pierwsze;
var
i, a, b, wyn: longint;
sitko: array[1..JakasLiczba] of boolean;
begin
writeln('Podaj dolna granice przedzialu: '); read(a);
writeln('Podaj gorna granice przedzialu: '); read(b);
wyn:=0;
//TUTAJ FRAGMENT KTORY ROBI SITO ERATOSTENESA z tablicy od 1.. do b
for i:=a to b do if sitko_zrobione[i]=TRUE then inc(wyn);
writeln('W zadanym przedziale jest ',wyn,' liczb pierwszych');
readln;
end.
komentarz:
- inc(zmienna_calkowita) jest równoważne zwiększeniu zmiennej o 1, czyli tak samo jak wyn:=wyn+1;
- tak na prawdę, nie musimy dawać: if "sitko_zrobione[i]=TRUE". wystarczy, że damy "if sitko_zrobione[i]". do instrukcji warunkowej IF trzeba przekazać wartość logiczną - a taką wartość mamy w tablicy dla i-tej liczby - albo TRUE, albo false. nieznacznie szybciej byłoby zastosowanie drugiego "if sitko_zrobione[i]", ponieważ przekazujemy instrukcji od razu wartość logiczną. natomiast w przypadku "if sitko_zrobione[i]=TRUE", najpierw podana jest wartość logiczna (np, jeśli i=7, wartość będzie true), a potem jakaś inna wartość, z którą ją porównujemy, tzn koniec końców, kompilator jeszcze oblicza wartość wyrażenia TRUE=TRUE lub FALSE=TRUE, czego nie ma przy zastosowaniu "if sitko_zrobione[i]" - ale to taki mały szczegół ;)
zadanie dla ciebie: napisz fragment programu, która zrobi "sitko" logiczne z tablicy [1..b] of boolean.
wskazówki: dla jedynki od razu zainicjuj FALSE, dla dwójki TRUE. ( sitko[1]:=false; sitko[2]:=true; )
i potem walnij pętlę, for i:=2 to b. jeśli natkniesz się na wartość prawdziwą, np. dla liczby 5, to znaczy że ta liczba jest pierwsza - i dla każdej jej wielokrotności w sitku ustaw wartość FALSE (odpowiedzialna za to inna pętla). możesz zastosować jakąś zmienną "mnoznik" żeby wiedzieć jakie wielokrotności wykreślać, i potem zrobić:
Kopiuj
//fragment programu
mnoznik:=5;
for i:=2 to (b div mnoznik) do sitko[i]:=FALSE;
//koniec fragmentu
praktycznie wszystko masz podane - wystarczy trochę pogłówkować i złożyć to do kupy ;) Jeśli coś nie jest jasne - pisz