Skocz do zawartości

Problem z algorytmem


Perykles

Polecane posty

Witam,

Niedawno zająłem się programowaniem w Pascalu. Próbowałem zrobić algorytm obliczający silnię, ale cały czas wyskakują jakieś błędy i nie mogę tego skompilować.

 

var
   n,s,i:integer;
begin
   writeln(Program obliczajacy silnie);
   writeln(Podaj liczbe, z ktorej chcesz obliczyc silnie :);
   readln(n);
   s:=1
   i:=n
   repeat
       s:=s-i
       i:=i-1
   until i<=1
   writeln(s);
end.[pascal]

 

Nie wiem co jest nie tak :P Jestem nowicjuszem w programowaniu :P Gdzie tu jest błąd?

Link do komentarza
Udostępnij na innych stronach

var
n,s,i:integer;
begin
writeln(Program obliczajĄcy silnie);
writeln(Podaj liczb, z ktrej chcesz obliczy† silni: );
readln(n);
s:=1
i:=n
repeat
 s:=s-i
 i:=i-1
until
 i<=1
writeln(s);
End.[pascal]

 

 

łoł , ale styl :angry:

 

lepiej kup książkę albo znajdź jakiś kurs

 

a tu masz rozwiązanie http://www.unit1.pl/67,txt

 

Pozdrawiam!

Link do komentarza
Udostępnij na innych stronach

OK, pobawmy się.

Możesz mnie uświadomić, w jaki sposób

s:=1
i:=n
repeat
 s:=s-i
 i:=i-1
until
 i<=1

liczy silnię?

Z tego co pamiętam, silnia liczby to iloczyn tej liczby i wszystkich niezerowych liczb naturalnych mniejszych od niej

Można to zaprogramować na 2 sposoby, iteracyjnie, albo rekurencyjnie.

Algorytm iteracyjny wygląda tak:

bierzesz sobie zmienną zawierającą dotychczasowy iloczyn i inicjujesz go wartością neutralną - ważne, neutralną

bierzesz inną zmienną i pakujesz do niej liczbę, z której silnię będziesz liczyć

w pętli przypisujesz do dotychczasowego iloczynu wynik mnożenia dotychczasowego iloczynu przez liczbę, a liczbę zmniejszasz o 1.

do czasu, gdy liczba osiągnie wartość 1

 

To jest gotowy, działający algorytm. I teraz 2 zadania.

Banalne: przepisz to na język zrozumiały dla komputera

Dające mi odrobinę sadystycznej przyjemności: przepisz ten kod tak, żeby nie wywalił się przy liczeniu silni dla 40

Link do komentarza
Udostępnij na innych stronach

Dzięki za informacje. Zrobiłem tak:

 

Uses crt;
var
s,i,n:longint;
Begin
clrscr;
Writeln('Wpisz liczbe: ');
Read(n);
 s:=1;
 i:=n;
  Repeat
   s:=s*i;
   i:=i-1;
  Until i<=1;
Writeln(s);
 Delay(3000);
End.

 

Wszystko działa, dzięki za pomoc. Nareszcie to zrozumiałem :) Problem tylko w tym, że wywala przy s>5. Co mam zrobić żeby przy większych liczbach nie wywalało?

Link do komentarza
Udostępnij na innych stronach

Od razu coś z zakresu optymalizacji:

Read(n);

i:=n;

 

Jesteś pewny, że potrzebujesz zarówno zmiennej i jak i zmiennej n?

Twoj longint jest trochę short. 5! zmieści Ci się w zmiennej typu byte (8 bitów)

8! w word lub shortint (chyba oba mają 16 bitów)

12! w int (32 bity)

20! w longint (64 bity)

Oczywiście podałem długości zmiennych unsigned.

 

Kompilator wywala jakiś błąd?

 

To jest gotowy, działający algorytm. I teraz 2 zadania.

2) Dające mi odrobinę sadystycznej przyjemności: przepisz ten kod tak, żeby nie wywalił się przy liczeniu silni dla 40

a no musisz sobie sam napisać obsługę zmiennych liczbowych o większej długości. Najłatwiej jest zadeklarować stringa i operować na kolejnych znakach. A że takie rozwiązanie jest do dupy, to inna sprawa. Trochę lepiej będzie na tablicach bajtów, gdzie każdy bajt przyjmuje wartości z zakresu 0-9. Ale nie po to mamy procesor zdolny przeliczać 4 bajty na raz, żeby go katować 10x większą ilością mnożeń, zwłasza, że mamy do dyspozycji inty i longi.

BTW: 40!

Przyznaję, że ja tutaj poszedłem trochę na łatwiznę, ale ostatecznie ja wieszam się na kablach, a nie na pętlach. A bc to rewelacyjny wynalazek :)

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...