delphi liczby pierwsze

delphi liczby pierwsze
0

Witam, na początek chcę powiedzieć, że czytałam wszystkie wątki dotyczące liczb pierwszych na tym forum, więc proszę mnie nie kasować i odsyłać do wyszukiwarki. Jednym słowem: proszę o litość.

Mam do napisania kilka zadań na zaliczenie. Jestem na informatyce na studiach, ale nigdy wcześniej nie miałam do czynienia z programowaniem. Tak to jest jak głupia baba się uprze na polibudę tuż po liceum humanistycznym ;/ Mogę też dla usprawiedliwienia mej niewiedzy dodać, że na razie mieliśmy trzy godziny z jakimś zastępcą, który nic nam nie tłumaczył itd... Dlatego proszę, podpowiedzcie mi jak ruszyć te programy. Nie chcę gotowców - ja naprawdę chcę to zrozumieć. I na serio czytam książki, szukam w necie - ale nie ogarniam.

No to do rzeczy. Polecenie brzmi: Napisz program wypisujący wszystkie liczby pierwsze z przedziału [a,b].

Moim pierwszym problemem jest jak zrobić ten przedział. Kombinowałam coś żeby były polecenia typu: podaj najmniejszą liczbę, podaj największą liczbę, ale nie wiem co dalej. Myślałam o jakiejś tablicy, ale nie wiem jak to ruszyć.

0

Hmmm, na podstawie tego co znalazłam w necie coś takiego na razie mi wyszło... Mógłby ktoś się wypowiedzieć? Działać działa, choć strasznie dużo enterów trzeba klikać...

Kopiuj
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

   var i,j,L,a,b: Integer;
begin
  write('podaj najmniejsza liczbe ');
  readln(a);
  write('podaj najwieksza liczbe ');
  readln(b);

  for a:=a to b do begin
     L:=0;
     for j:=1 to a do
     if (a mod j)=0 then L:=L+1;
     if L= 2 then writeln(a);
     readln;

  end;

end.
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Do tego użyj for'a.

Kopiuj
Program LiczbyPierwsze;                              { Nazwa programu                      }
{$APPTYPE CONSOLE}                                   { Ustalenie, że to program konsolowy  }
Var IleLiczb, I: Integer;                            { Zmienne                             }

Function CzyLiczbaPierwsza(P: Integer): Boolean;     { Funkcja                             }
Var I: Integer;                                      { Zmienna                             }
Begin                                                { Początek funkcji                    }
 Result := True;                                     { Ustawienie wyniku na 'tak'          }
 I      := 2;                                        { Ustawienie zmiennej I na 2          }
 While (I < P) Do                                    { Dopóki I < P                        }
  if (P Mod I = 0) Then                              { Jeżeli P Mod I = 0                  }
  Begin
   Result := False;                                  { Liczba nie jest liczbą pierwszą     }
   Break;                                            { Przerwij działanie pętli While      }
  End
  Else                                               { Jeżeli P Mod I <> 0                 }
  Inc(I);                                            { Zwiększ I o 1                       }
End;                                                 { Koniec funkcji                      }

Begin                                                { Główny blok programu                }
 WriteLn('*** Obliczanie liczb pierwszych ***');     { Wstęp                               }
 WriteLn;                                            { (enter)                             }
 Write('Ile liczb znalezc: ');                       { Ile liczb znaleźć ?                 }
 ReadLn(IleLiczb);                                   { Zczytaj wartość od użytkownika      }
 For I := 2 To IleLiczb Do                           { Pętla, od I do 'IleLiczb'           }
  if (CzyLiczbaPierwsza(I)) Then                     { Jeżeli 'CzyLiczbaPierwsza(I)' = TAK }
   WriteLn(I);                                       { Wyświetl tę liczbę                  }
 ReadLn;                                             { Czekaj na enter                     }
End.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Ubiegłaś mnie, jak pisałem posta...

Kopiuj
program Project2;

{$APPTYPE CONSOLE}

uses
  SysUtils;

   var i,j,L,a,b, mi: Integer;
begin
  write('podaj najmniejsza liczbe ');
  readln(mi);
  write('podaj najwieksza liczbe ');
  readln(b);

  for a:=mi to b do begin
     L:=0;
     for j:=1 to a do
     if (a mod j)=0 then L:=L+1;
     if L= 2 then writeln(a);


  end;
     readln; //ReadLn tutaj i nie trzeba naciskać co liczbę
end.

Ale dobrze wyświetla ;)

Kopiuj
for a:=a to b do begin

Tak się nie robi ! (na przyszłość).


edytowany 1x, ostatnio: Patryk27
0

A możesz powiedzieć mi co miałeś na myśli pisząc 'tak się nie robi'? Mówię wprost - nie napisałam tego zupełnie sama, przerabiałam tylko te programy, które znalazłam w sieci, więc choć widzę, że działa i wiem na jakiej zasadzie (sprawdza czy każda liczba jest podzielna tylko przez samą siebie i jeden) to dopiero próbuję dokładnie to rozgryźć w razie nauczyciel by nas spytał dlaczego tak a nie inaczej.
I wielkie dzięki za to przestawienie 'readln' bo się głowiłam jak sprawić, by nie trzeba było tyle klikać :*

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

To tak trochę nielogicznie wygląda (wg.mnie).

Kopiuj
For A:=A To B Do

Ale to zależy od programisty (programistki) jak użyje ;)
Może ktoś inny się wypowie ?


0

Aha, łapię ;) Twoją wersję przeanalizowałam sobie jeszcze i jest dla mnie bardziej zrozumiała, ale ma tę wadę, że najmniejsza liczba jest stałą, a konkretniej dwójką. Póki co zostanę więc przy 'moim' pomyślę. Mógłbyś jeszcze (lub ktokolwiek inny) trochę mi 'objaśnić' mój kod?

Tzn. tak liczę w pętli od 'j' do którego jest przypisana jedynka do 'mi'. Sprawdzam, czy reszta z dzielenia 'mi' przez 'j' jest równa 0. Jeśli tak to do L dodaje 1 i w ten sposób powstaje kolejne nowe L, większe o jeden. I potem jeśli L jest równe dwa wypisuję a. I teraz proszę o wyjaśnienie czym jest to całe L??? Jeśli pytam jak klasyczny nieuk to bardzo przepraszam, ale staram się to pojąć... :)

0

Dobra, dobra, przepraszam, już wiem - L to ilość takich wyników, gdy reszta wynosi 0. I jeśli są tylko dwa takie wyniki to mamy liczbę pierwszą :D Musiałam to sobie tylko rozpisać ;))) Matko, a cały dzień nad tym programem siedziałam (nie wspominając o wielu podejściach w dni poprzednie)... :))))

MarkusB
  • Rejestracja:ponad 19 lat
  • Ostatnio:ponad 2 lata
0

Hallo wampirzyc(a)!

W zasadzie nie wiem, czy powinienem to robic, ale jest pewna strona pewnego liceum w Tarnowie z wieloma rozwazaniami pewnych szkolnych problemow. Wpadlem na nia przypadkiem i bardzo mi sie spodobala. Zagladam tam od czasu do czasu bo czytanie zamieszczonego tam kodu to bardzo dobra gimnastyka!

Podaje link do Twojego problemu: http://edu.i-lo.tarnow.pl/inf/alg/001_search/0009.php

Pozdrawiam
Markus
:-)


Go Hard Or Go Home
edytowany 3x, ostatnio: MarkusB
GL
  • Rejestracja:ponad 14 lat
  • Ostatnio:około 14 lat
  • Postów:6
0

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:

  1. inc(zmienna_calkowita) jest równoważne zwiększeniu zmiennej o 1, czyli tak samo jak wyn:=wyn+1;
  2. 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

0

A ja kiedyś bawiąc sie liczbami pierwszymi doszedłem do wniosku ze nie ma sensu badać czy liczba n dzieli się przez którąkolwiek z zakresu (2; sqrt(n)). Wystarczy zamiast tego badać, czy liczba n dzieli się przez którąkolwiek liczbę PIERWSZĄ z zakresu (2, sqrt(n)). Wtedy można zrobić np sympatyczną listę, z której będą brane liczby pierwsze, które będą służyły do badania czy następna liczba jest pierwsza. Jeśli jest - trafia ona na tą listę. Takie jakby sprzężenie zwrotne. Wyniki działania prędzej czy później będą jego danymi.

0

Jeżeli jest niewielka ilość liczb do sprawdzenia, sprawdzanie do pierwiastka jest dobre (jeśli nie ma podzielnika w zakresie do pierwiastka z liczby, to nie będzie w zakresie powyżej pierwiastka, bo liczba jeśli ma szukane podzielniki to jest iloczynem dwóch liczb albo równych pierwiastkowi z niej albo jedna mniejsza od pierwiastka a druga większa).

Przy dużych zakresach do sprawdzenia, rozpoczynających się od zera, sito Eratostenesa jest dużo szybsze.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 11 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10056
0

A żę tak spytam z ciekawości.
po co to

Kopiuj
a := 1;
for a := mi to b do

?

Zamiast mi mogła wstawić 1.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)