GRY-Online.pl --> Archiwum Forum

Programowanie - Prosba o pilna i fachowa pomoc.

06.09.2004
18:20
smile
[1]

Maevius [ Czarownik Budyniowy ]

Programowanie - Prosba o pilna i fachowa pomoc.

Prosze o pilna pomoc w zdebugowaniu programu. Nie liczy tak jak powinien, gubi sie przy dluzszych wyrazeniach w nawiasach. Strasznie szybko potrzeba mi ta sprawnie dzialajaca aplikacje, jesli jest to
zbyt skomplikowana robota - zaplace. Nie mam juz pojecia dlaczego sie sypie.

Kod programu i moje objasnienia:


======================

Program Kalkulator_binarny;
uses crt;

var
liczby:array[1..100] of real;
znak:array[1..100] of char;
nawias:array[1..100] of integer;
wynik,kkk:integer;
w:real;
wybor,wyrazenie:string;
i,j,code:integer;
wyr:string;



procedure przesun (x:integer);
var i:integer;
begin

for i:=x to kkk do
begin
nawias:=nawias[i+1];
znak:=znak[i+1];
liczby:=liczby[i+1];
end;

end;



function oblicz (odkad,dokad:integer):real;
label 0,1,2;

var
n,b:integer;
tmp:real;

begin

0:
n:=0;b:=0;

for i:=odkad to dokad do
begin
if nawias>0 then b:=i; ‹Sprawdza czy sa nawiasy, jesli sa to zaglebia sie
coraz bardziej w wyrazenie, az napotka na wyrazenie bez nawiasow, wtedy idzie
dalej i wykonuje najpierw mnozenie/dzielenie a pozniej dodawanie/odejmowanie›

if (nawias<0) and (b<>0) then
begin
dec(nawias);
inc(nawias);
tmp:=oblicz(b,i-1);
dec(dokad,i-1-b);
goto 0;
end;

end;


for i:=odkad to dokad do ‹Mnozenie i dzielenie›
begin
1:
if (i <= dokad) then
‹Mnozy, przesuwa - to jest zamiast pomnozonych liczb wstawia liczbe i liczy dalej›
begin
if znak = '*' then begin w:=liczby*liczby[i+1];przesun (i);liczby:=w;dec(dokad);goto 1;end;
if znak = '/' then begin w:=liczby/liczby[i+1];przesun (i);liczby:=w;dec(dokad);goto 1;end;
end;
end;


for i:=odkad to dokad do ‹Dodawanie i odejmowanie›
begin
2:
if (i <= dokad) then
‹Jak powyzej, dodaje, wstawia liczbe, dodaje....›
begin
if znak = '+' then begin w:=liczby+liczby[i+1];przesun (i);liczby:=w;dec(dokad);goto 2;end;
if znak = '-' then begin w:=liczby-liczby[i+1];przesun (i);liczby:=w;dec(dokad);goto 2;end;
end;
end;

oblicz:=liczby[odkad];
end;

Function DziesBin (liczba: integer): string;
Var
Tab: array [1..100] of char;
last, i: integer;
wynik: string;
begin;
for i:=100 downto 1 do begin;
Tab:='0';
if (liczba mod 2) = 1 then begin;
Tab:='1';
last:=i;
end;
liczba:=(liczba div 2);
end;
for i:=last to 100 do wynik:=wynik+Tab;
DziesBin:=wynik;
end;


Function BinDzies (wyr: string): integer;
Var ggg, h, wartosc, dod, wykladnik: integer;
begin;
wartosc:=0;
dod:=1;
for ggg:=length(wyr) downto 1 do begin;
if wyr[ggg]='1' then wartosc:=wartosc+dod;
dod:=dod*2;
end;
BinDzies:=wartosc;
end;


procedure rozdziel (wyrazenie:string);
begin
j:=1;wyr:='';
for i:=1 to 100 do nawias:=0;
for i:=1 to length (wyrazenie) do
begin
if (wyrazenie='(') then begin inc(nawias[j]);end;
if (wyrazenie=')') then begin dec(nawias[j]);end;
if (wyrazenie>='0') and (wyrazenie<='1') then wyr:=wyr+wyrazenie;
if (wyrazenie='+') or (wyrazenie='-') or (wyrazenie='*') or (wyrazenie='/') or (i=length(wyrazenie)) then
begin
liczby[j]:=BinDzies(wyr);
znak[j]:=wyrazenie;
wyr:='';
kkk:=j;
inc (j);
end;

end;
end;

label 1;
begin
clrscr;
writeln ('Podaj wyrazenie do obliczenia : ');
readln (wyrazenie);
rozdziel (wyrazenie);
writeln ('Wynik w postaci dziesietnej to: ',(oblicz(1,kkk)):0:0);
writeln ('Czy chcesz zobaczyc wynik w postaci binarnej ? (Tylko jego czesc calkowita) (t/n)');
readln (wybor);
if wybor='t' then begin;
writeln ('Wpisz czesc calkowita wyniku:');
readln (wynik);
writeln ('Wynik w postaci binarnej to: ',DziesBin(wynik));
end;
writeln ('Nacisnij dowolny klawisz by zakonczyc.');
readkey;


end.

======================

Ponizej w linku jest caly skompilowany program.

06.09.2004
18:36
[2]

Maevius [ Czarownik Budyniowy ]

Czyzby Turbo Pascal oczko wyzej nisz licealne "napisz program ktory sumuje a i b" okazal sie zbyt trudnym wyzwaniem dla forumowych programistow ? :P

06.09.2004
19:44
smile
[3]

Chupacabra [ Senator ]

tak na pierwszy rzut oka to to to nie za bardzo skonczone jest:) A tak bajdelej, szukales na googlu? Bo kalkulatorow to jest w kazdym jezyku i w setkach wersji. Ja taki jak ty zrobilem w javie, ale programista ze mnie cienki i sie meczylem z tym niezle, a pascala juz troche nie pamietam:)
BTW na informatyce jestes?

06.09.2004
19:50
[4]

Maevius [ Czarownik Budyniowy ]

Chupacabra - No na informatyce, a to jest projekt zalegly z semestru zimowego ;) Ja do pascala nigdy nie mialem ochoty - stad moje zaleglosci. Binarnego szukalem w pascalu i znalezc nie moglem, ech. Pomozesz ?

06.09.2004
20:02
[5]

Mark24 [ >>>Martinez751<<< ]

to to jest oczko wyżej niż liceum? :P
Ja bym to napisał całkiem inaczej, połowy programu nie czaję - szybciej bym napisał taki kalkulator od nowa. Całkiem inny tok myślenia.
1. wpisuję wyrażenie
2. Sprawdzam czy są nawiasy
a) są - szukam PIERWSZEGO znaku ")"
a1) znajduję - więc cofam się w tył i szukam pierwszego znaku "("
a2) wykonuję działanie w nawiasie wpierw mnożenie, potem dodawanie
a3) podstawiam liczbę kasuję nawiasy
3) wracam do punktu drugiego
jezeli nawiasów już nie ma skaczę do punktu a2

Ładnie to przemyśleć, napisać i wszystko.

09.09.2004
09:41
[6]

Maevius [ Czarownik Budyniowy ]

Mark, tak oczko wyzej, bo to kalkulator binarny, a to troche komplikuje sprawe. Program ma liczyc wyrazenia typu 010101 + 0101011 - ((( 010101 * 010101 - 0101) * 0101 + 0101) - 0101 + 0101) - 01010.
I nie zawsze liczy prawidlowo, wysypuje sie, zwraca 0.

Help !

09.09.2004
10:18
[7]

grish_em_all [ Hairless Cobra ]

maevius--> ile masz czasu na zrobienie tego sprzetu, bo ja przeszedlem przez TP i Delphi z palcem w tozsamosci, potrzebuje tylko kilku dni na przeanalizowanie tego i ew. poprawki.
P.S. jakbys mogl wyslac mi na maila Turbo Pascala i kod programu to bylbym wdzieczny (poszloby szybciej)

09.09.2004
10:47
[8]

Eliash [ Generaďż˝ ]


Maevius -> Nie mam teraz czasu na jakieś wywody :) tylko mały hint...

Kalkulatorów tak się nie pisze, podane wyrazenie nalezy zamienić na Odwrotną Notację Polską (Reverse Polish Notation) i wtedy policzyć.
Garść informacji: Polski matematyk (w właściwie logik) Jan Łukasiewicz udowodnił że każde wyrażenie zawierajace nawiasy można uprościć i owych nawiasów się pozbyć, wymyślił "Notację Polską" za pomocą którem można zapisac każde wyrażenie matematyczne bez pomocy nawiasów.
Notację Polską odwrócono bo tak było wygodniej dla programistów i tak powstała ONP.

Gdzieś miałam kalkulator dzisiętny napisany jeszcze na pierwszym roku studiów, jak znajdę to Ci prześlę, nie powinieneś mieś problemów z przerobieniem go binarny.


09.09.2004
12:30
[9]

fanlegii79 [ Konsul ]

Odwrotna notacja polska jest wygodniejsza dla informatykow, bo kazde wyrazenie w niej zapisane mozna policzyc uzywajac jedynie jednego stosu. Dlatego kiedys kalkulatory HP uzywaly ONP, bo dzieki temu mogly liczyc duzo szybciej. Natomiast konwertowanie wyrazenia do ONP tylko aby je policzyc to lekka przesada. ja oczywiscie bym to napisal tak jak proponuje to mark24. pozostaje jeszcze pytanie jak wydajnie to reprezentowac, ale jezeli nie ma jakis konkretnych zalozen co do wielkosci liczb dlugosci wyrazenia i ilosci zagniezdzenia to bym zrobil z tego po prostu na kolejce dwu kierunkowej. Struktura odpowiednio dla nawiasu, operacji i liczby. I jezeli bym znalazl znak ")" to bym sie cofal wykonujac mnozenia i dzielenia az dojde do "(" a wtedy bym go kasowal i szedl na przod wykonujac dodawania i mnozenia i kasujac koncowy ")" Oczywiscie trzeba uwazac zeby nie "przekrecic" wyrazenia i pomijamy narazie sprawdzanie czy dane wyrazenie jest poprawne.

© 2000-2024 GRY-OnLine S.A.