Nadesłany przez Michał Knasiecki, 26 lipca 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Notacja/Unit1.pas:
//Program pobrano ze strony www.algorytm.org
//Opracował Michał Knasiecki
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus;
type
TForm1 = class(TForm)
Edit1: TEdit; //Notacja infiksowa -wejscie
Edit2: TEdit; //ONP -wyjscie
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Bevel1: TBevel;
Button2: TButton;
MainMenu1: TMainMenu;
Plik1: TMenuItem;
Wczytajnotacjinfiksow1: TMenuItem;
ZapiszONP1: TMenuItem;
N1: TMenuItem;
Zakoncz1: TMenuItem;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Wczytajnotacjinfiksow1Click(Sender: TObject);
procedure ZapiszONP1Click(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit2Change(Sender: TObject);
procedure Zakoncz1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TYPE wskaznik_stosu=^skladnik_stosu;
skladnik_stosu=record
dane:char;
wskaznik:wskaznik_stosu;
end;
var
Form1: TForm1;
Liczba_Nawiasow:integer=0;
implementation
function priorytet(op:string):byte; //bada priorytet operatora
begin
if (op='(') then result:=0;
if (op='+')or(op='-') then result:=1;
if (op='*')or(op='/') then result:=2;
end;
function sprawdzenie(c:char):byte;
begin
if (c='*')or(c='/')or(c='+')or(c='-') then result:=1; //else
//result:=2;
if (c in['a'..'z'])or(c in['A'..'Z'])or(c in['0'..'9']) then result:=2;
if c=')' then result:=0;
if c='(' then result:=3;
end;
procedure nastos(var element:char;
var wierzcholek:wskaznik_stosu); //Dodaje na stos
var punkt:wskaznik_stosu;
begin
punkt:=wierzcholek;
New(wierzcholek);
with wierzcholek^ do
begin
dane:=element;
wskaznik:=punkt
end;
end;
procedure zestosu(var element:char;
var wierzcholek:wskaznik_stosu); //Zdejmuje ze stosu
var punkt:wskaznik_stosu;
begin
if wierzcholek<>nil then
begin
with wierzcholek^ do
begin
element:=dane;
punkt:=wskaznik;
end;
Dispose(wierzcholek);
wierzcholek:=punkt;
end;
end;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var s:string; //dzialanie wczytane z edit1.text
// {c,}c2:string; //zmienna pomocnicza do badania liczb i operatorów
//t:string; //zmienna pomocnicza do wczytywania operatorów ze stosu
i:integer; //licznik
element,wierzcholek:wskaznik_stosu;
c,t,c2:char;
begin
edit2.clear;
s:=edit1.text; //wczytaj wyrażenie
wierzcholek:=nil; //Dno stosu
i:=0;
repeat //Badaj wyrażenie znak po znaku
inc(i);
c:=s[i]; //Jesli trafiles na:
if (c='-')and(i=1) then //Pierwsza liczba jest ujemna
begin
edit2.text:=edit2.text+c;
inc(i);
c:=s[i];
end;
if sprawdzenie(c)=0 then //1- Nawias zamknięty
begin
Dec(Liczba_Nawiasow);
if not(wierzcholek=nil) then begin //Jesli stos nie jest pusty
element:=wierzcholek;
repeat
t:=element^.dane;
element:=element^.wskaznik;
zestosu(t,wierzcholek); //Zdejmij z niego wszystkie operatory
if not(t='(') then
edit2.text:=edit2.text+t; //i wypisz wszystko oprócz nawiasu
until (element=nil)or(t='(');
end;
end;
if sprawdzenie(c)=2 then edit2.text:=edit2.text+c; //2- Liczby wypisz na wujscie
if sprawdzenie(c)=3 then begin
nastos(c,wierzcholek); //3- Nawias otwarty wrzuc na stos
Inc(Liczba_Nawiasow);
c2:=s[i+1];
if c2='-' then //Jesli następną liczbą jest l.ujemna
begin
edit2.text:=edit2.text+c2; //przepisz na wyjscie minus
inc(i);
end;
end;
if sprawdzenie(c)=1 then //4- Dzialanie
begin
if(sprawdzenie(s[i-1])=2) then
edit2.text:=edit2.text+' '; //Odstęp między argumentami
if not(wierzcholek=nil) then begin
element:=wierzcholek;
repeat
t:=element^.dane;
element:=element^.wskaznik;
if priorytet(c)<=priorytet(t) then //Zdejmij ze stosu dzialania (t) o
begin //priorytecie większym lub równym (c)
zestosu(t,wierzcholek); //i wypisz na wyjscie
edit2.text:=edit2.text+t;
end;
until (element=nil)or(priorytet(t)<priorytet(c));
end;
NaStos(c,wierzcholek); //Nastepnie dodaj do stosu
end;
until i=strlen(Pchar(s));
if not(wierzcholek=nil)then //Wypisz wszystko, co zostalo na stosie
repeat
zestosu(t,wierzcholek);
edit2.text:=edit2.text+t;
until wierzcholek=nil;
if Liczba_Nawiasow<>0 then
begin
if Liczba_Nawiasow>0 then
MessageDlg('Wyrażenie zawiera zbyt nieprawidlową liczbę nawiasów'+
' zamykających. Jest ich o: '+inttostr(abs(liczba_nawiasow))+' za malo. Wprowadź korektę i wcisnij [Konwertuj]', mtError,
[mbCancel ], 0);
if Liczba_Nawiasow<0 then
MessageDlg('Wyrażenie zawiera zbyt nieprawidlową liczbę nawiasów'+
' zamykających. Jest ich o: '+inttostr(abs(liczba_nawiasow))+' za duzo. Wprowadź korektę i wcisnij [Konwertuj]', mtError,
[mbCancel ], 0);
Edit2.clear;
Liczba_Nawiasow:=0;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
application.Terminate;
end;
procedure TForm1.Wczytajnotacjinfiksow1Click(Sender: TObject);
var f:textfile;
s:string;
begin
edit2.Clear;
if opendialog1.Execute then
begin
assignfile(f,opendialog1.filename);
reset(f);
readln(f,s);
edit1.text:=s;
closefile(f);
end;
button1.enabled:=true;
end;
procedure TForm1.ZapiszONP1Click(Sender: TObject);
var f:textfile;
begin
if savedialog1.Execute then
begin
assignfile(f,savedialog1.filename);
rewrite(f);
writeln(f,edit2.text);
closefile(f);
end;
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
if button1.enabled=false then button1.enabled:=true;
end;
procedure TForm1.Edit2Change(Sender: TObject);
begin
if zapiszonp1.Enabled=false then zapiszonp1.Enabled:=true;
end;
procedure TForm1.Zakoncz1Click(Sender: TObject);
begin
application.terminate;
end;
end.

