| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- {
- Доступные операции:
- +-*/ - стандартно
- ^ - возведение в степень
- }
- const
- deyst = ['+','-','*','/','^',')','('];
- type
- pTree = ^tTree;
- tTree = record
- operand : real;
- operation : char;
- left : pTree;
- right : pTree;
- end;
- stack = ^tstack;
- tstack = record
- t : pTree;
- n : stack;
- end;
- {------------------------------}
- Procedure CreateBranch(var aStack : stack;aCurOper : char);
- var
- aN : pTree;
- aL : stack;
- begin
- if (aStack = nil) or (aStack^.n = nil) then
- begin
- WriteLn('Error in operators');
- Halt(255);
- end;
- New(aN);
- with aN^ do
- begin
- operation := aCurOper;
- Right:=aStack^.t;
- aL := aStack;
- aStack := aStack^.n;
- Dispose(aL);
- Left :=aStack^.t;
- aL:=aStack;
- aStack := aStack^.n;
- Dispose(aL);
- aL:=aStack;
- end;
- New(aStack);
- aStack^.n := aL;
- aStack^.t := aN;
- end;
- {------------------------------}
- function GetPrior(a:char):integer;
- begin
- case a of
- '(':GetPrior:=5;
- ')':GetPrior:=5;
- '+':GetPrior:=10;
- '-':GetPrior:=10;
- '*':GetPrior:=20;
- '/':GetPrior:=20;
- '^':GetPrior:=30;
- else begin
- WriteLN('Sorry, undefined operation, ''',a,'''');
- end;
- end;
- end;
- {------------------------------}
- function GetToken(var aStr:string;var aPos:byte):string;
- var
- ret:string;
- begin
- ret:='';
- while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
- if aStr[aPos] in Deyst then
- begin
- ret := aStr[aPos];
- inc(aPos)
- end
- else
- while (aStr[aPos] in ['0'..'9','.']) and (aPos <= ord(aStr[0])) do
- begin
- ret:=ret + aStr[aPos];
- inc(aPos);
- end;
- while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
- GetToken:=ret;
- end;
- {------------------------------}
- Function CreateTree(aInp:string):pTree;
- var
- operations : string;
- token : string;
- opPos,sPos : byte;
- LastOprtn : Boolean;
- retcode : integer;
- TreeStack : stack;
- NewEl : stack;
- begin
- sPos:=1;
- operations[0] := #255;
- LastOprtn := true;
- TreeStack := nil;
- opPos := 0;
- while sPos <= ord(aInp[0]) do
- begin
- Token := GetToken(aInp,sPos);
- if Token[1] in Deyst then
- begin
- if Token[1] <> '(' then
- if LastOprtn then
- begin
- WriteLn('Error in input: ',aInp);
- WriteLn('Expected operation at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
- Halt(236);
- end
- else
- while (opPos > 0) and (GetPrior(Token[1]) < GetPrior(operations[opPos])) do
- begin
- CreateBranch(TreeStack,operations[opPos]);
- dec(opPos);
- end;
- if Token[1] <> ')' then
- begin
- inc(opPos);
- operations[opPos] := Token[1];
- LastOprtn := true;
- end
- else
- Dec(opPos);
- end
- else
- begin
- if not LastOprtn then
- begin
- WriteLn('Error in input: ',aInp);
- WriteLn('Expected operand at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
- Halt(236);
- end;
- New(NewEl);
- NewEl^.n := TreeStack;
- new(NewEl^.t);
- with NewEl^.t^ do
- begin
- left:=nil;
- right:=nil;
- Val(Token,operand,retcode);
- operation := ' ';
- if retcode <> 0 then
- begin
- WriteLn('Error in input: ',aInp);
- WriteLn('in position ',sPos-Length(Token));
- Halt(255);
- end;
- end;
- TreeStack := NewEl;
- LastOprtn := False;
- end;
- end;
- while opPos > 0 do
- begin
- CreateBranch(TreeStack,operations[opPos]);
- dec(opPos);
- end;
- CreateTree := TreeStack^.t;
- Dispose(TreeStack);
- end;
- {------=-=-=-=--==-=-=-=--=--==--=}
- Procedure ToPostfix(aT:pTree;var aOut:string);
- var
- aStr : string[13];
- begin
- if aT = nil then exit;
- ToPostfix(aT^.Left,aOut);
- ToPostfix(aT^.Right,aOut);
- if aT^.Operation = ' ' then
- begin
- Str(aT^.operand:0:0,aStr);
- aOut:=aOut+aStr+' ';
- end
- else
- aOut:=aOut+aT^.Operation+' ';
- end;
- {-----------------------}
- Function aInb(a,b:real):real;
- begin
- if a > 0 then
- aInb:=Exp(b*Ln(a))
- else
- aInb:=0;
- end;
- {-----------------------}
- Function CalculateTree(aT: pTree):real;
- begin
- if aT=nil then exit;
- Case aT^.Operation of
- ' ': CalculateTree:=aT^.Operand;
- '+': CalculateTree:=CalculateTree(aT^.Left) + CalculateTree(aT^.Right);
- '-': CalculateTree:=CalculateTree(aT^.Left) - CalculateTree(aT^.Right);
- '*': CalculateTree:=CalculateTree(aT^.Left) * CalculateTree(aT^.Right);
- '/': CalculateTree:=CalculateTree(aT^.Left) / CalculateTree(aT^.Right);
- '^': CalculateTree:=aInb(CalculateTree(aT^.Left),CalculateTree(aT^.Right));
- end;
- end;
- {-----------------------}
- Procedure DisposeTree(aT : pTree);
- begin
- if aT <> nil then
- Begin
- DisposeTree(aT^.Left);
- DisposeTree(aT^.Right);
- Dispose(aT);
- end;
- end;
- {-------}
- var
- aIn : string;
- aOut : string;
- Tree :pTree;
- begin
- Assign(input,'9.txt');
- {$I-}
- Reset(input);
- if IOResult <> 0 then
- begin
- WriteLn('File 9.txt not found!');
- halt(255);
- end;
- {$I+}
- Readln(aIn);
- Close(input);
- aOut :='';
- Tree := CreateTree(aIn);
- ToPostfix(Tree,aOut);
- Assign(OutPut,'9.out');
- Rewrite(OutPut);
- WriteLn('Выражение в постфикс. форме: ',aOut);
- WriteLn('Результат: ',CalculateTree(Tree):0:3);
- Close(output);
- DisposeTree(Tree);
- end.
|