Program, który dla podanego n wypisuje liczbę pierwszą o numerze n

0

Witam, pomoże ktoś mam do napisania program jak w temacie

Kolejnym liczbom pierwszym nadajemy numery w następujący sposób:

  • liczba pierwsza 2 ma numer 0,
  • liczba pierwsza 3 ma numer 1,
  • liczba pierwsza 5 ma numer 2,
  • liczba pierwsza 7 ma numer 3, itd.
    Napisz program, który dla podanego n wypisuje liczbę pierwszą o numerze n.

jedyne co udało mi się zrobić to napisać funkcje z której muszę skorzystac mianowicie

Function prime(n:longint):boolean;
var d:longint;

begin
d:=2;
    while ((d<n) and (n mod d <>0)) do
        begin
            d:=d+1;
        end;
    if d=n then prime:=true
        else prime:=false;
end;

z góry dziekuje za pomoc

0

Najpierw może skupmy się na funkcji sprawdzającej czy zadana liczba jest liczbą pierwszą; Nie podałeś nazwy środowiska którego używasz do pisania kodu, więc podam przykład dla kompilatora FPC:

function IsPrimeNumber(ANumber: Integer): Boolean;
var
  LDivider: Integer = 2;
begin
  while (ANumber > LDivider) and (ANumber mod LDivider <> 0) do
    LDivider += 1;

  Result := ANumber = LDivider;
end;

Prawda, że prościej, krócej i czytelniej? Teraz czas na funkcję, która w argumencie przyjmie indeks liczby pierwszej (ten ustalony indeks według zadanego schematu), a zwróci wartość szukanej liczby:

function PrimeNumberByIndex(AIndex: Integer): Integer;
begin
  Result := 1;

  while AIndex >= 0 do
  begin
    Result += 1;

    while not IsPrimeNumber(Result) do
      Result += 1;

    AIndex -= 1;
  end;
end;

Powyższa funkcja też nie wydaje się być skomplikowana, więc nie ma co tłumaczyć; Chyba że czegoś nie rozumiesz to daj znać, a opiszę jej działanie; W każdym razie i tak przeanalizuj ten kod, abyś wiedział jak działa i dlaczego działa; Pozostał jeszcze kod używający tej funkcji:

var
  LIndex: Integer = 0;
begin
  while LIndex < 20 do
  begin
    WriteLn(LIndex:2, ' - ', PrimeNumberByIndex(LIndex));
    LIndex += 1;
  end;
end.

Służy do wypisania na ekranie wartości pierwszych dwudziestu liczb pierwszych, o przyjętych indeksach z zakresu od 0 do 19; Wyjście w konsoli wyglądać będzie następująco:

 0 - 2
 1 - 3
 2 - 5
 3 - 7
 4 - 11
 5 - 13
 6 - 17
 7 - 19
 8 - 23
 9 - 29
10 - 31
11 - 37
12 - 41
13 - 43
14 - 47
15 - 53
16 - 59
17 - 61
18 - 67
19 - 71

http://ideone.com/u4VK7x

0

nie rozumie tego zapisu


    while not IsPrimeNumber(Result) do
      Result += 1;

    AIndex -= 1;
0

W niejawnej zmiennej Result znajduje się tymczasowa wartość; Iterowana jest od 2 (pierwszy przebieg pętli) po kolei co 1 i dla każdej liczby sprawdzane jest za pomocą funkcji IsPrimeNumber czy jest pierwsza; Dopóki sprawdzana liczba nie jest pierwszą, inkrementowana jest o 1;

Parametr AIndex pierwotnie zawiera indeks szukanej liczby pierwszej; Wewnętrznie, czyli dla funkcji PrimeNumberByIndex, służy także jako zmienna (drugą dodatkową zmienną jest Result); Główna pętla While musi zostać wykonana tyle razy, ile pierwotnie wynosi argument AIndex plus 1, bo indeks pierwszej liczby pierwszej to 0;

Parametr AIndex oraz Result traktowane są jako dodatkowe zmienne; Równie dobrze można by ten kod napisać tak:

function PrimeNumberByIndex(AIndex: Integer): Integer;
var
  LNumber: Integer = 1;
  LIndex: Integer = -1;
begin 
  while LIndex < AIndex do
  begin
    LNumber += 1;
 
    while not IsPrimeNumber(LNumber) do
      LNumber += 1;
 
    LIndex -= 1;
  end;
  
  Result := LNumber;
end;
0

To jest to samo co:

Result:=  Result  + 1;

i

AInde:= AIndex - 1;
0

Oraz to samo co Inc i Dec;

Należy też wspomnieć, że funkcja IsPrimeNumber nie powinna szukać dzielników dotąd aż ten dzielnik zrówna się z liczbą, a do zaokrąglonego pierwiastka kwadratowego liczby wejściowej; Można też inkrementować dzielnik co 2, a nie co 1, dlatego że żadna parzysta liczba (oprócz 2) nie jest liczbą pierwszą; Dzięki temu zmniejszymy liczbę iteracji o ponad połowę, względem bieżącej wersji sugerowanego kodu;

Natomiast ten zapis:

while not IsPrimeNumber(Result) do
  Result += 1;

AIndex -= 1;

to nic innego jak ten:

while IsPrimeNumber(Result) = False do
  Inc(Result);
  
Dec(AIndex);

Tyle że jest krótszy i IMHO czytelniejszy.

0

Dziekuje za pomoc

1 użytkowników online, w tym zalogowanych: 0, gości: 1