9.PAS 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. {
  2. Доступные операции:
  3. +-*/ - стандартно
  4. ^ - возведение в степень
  5. }
  6. const
  7. deyst = ['+','-','*','/','^',')','('];
  8. type
  9. pTree = ^tTree;
  10. tTree = record
  11. operand : real;
  12. operation : char;
  13. left : pTree;
  14. right : pTree;
  15. end;
  16. stack = ^tstack;
  17. tstack = record
  18. t : pTree;
  19. n : stack;
  20. end;
  21. {------------------------------}
  22. Procedure CreateBranch(var aStack : stack;aCurOper : char);
  23. var
  24. aN : pTree;
  25. aL : stack;
  26. begin
  27. if (aStack = nil) or (aStack^.n = nil) then
  28. begin
  29. WriteLn('Error in operators');
  30. Halt(255);
  31. end;
  32. New(aN);
  33. with aN^ do
  34. begin
  35. operation := aCurOper;
  36. Right:=aStack^.t;
  37. aL := aStack;
  38. aStack := aStack^.n;
  39. Dispose(aL);
  40. Left :=aStack^.t;
  41. aL:=aStack;
  42. aStack := aStack^.n;
  43. Dispose(aL);
  44. aL:=aStack;
  45. end;
  46. New(aStack);
  47. aStack^.n := aL;
  48. aStack^.t := aN;
  49. end;
  50. {------------------------------}
  51. function GetPrior(a:char):integer;
  52. begin
  53. case a of
  54. '(':GetPrior:=5;
  55. ')':GetPrior:=5;
  56. '+':GetPrior:=10;
  57. '-':GetPrior:=12;
  58. '*':GetPrior:=20;
  59. '/':GetPrior:=20;
  60. '^':GetPrior:=30;
  61. else begin
  62. WriteLN('Sorry, undefined operation, ''',a,'''');
  63. end;
  64. end;
  65. end;
  66. {------------------------------}
  67. function GetToken(var aStr:string;var aPos:byte):string;
  68. var
  69. ret:string;
  70. begin
  71. ret:='';
  72. while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
  73. if aStr[aPos] in Deyst then
  74. begin
  75. ret := aStr[aPos];
  76. inc(aPos)
  77. end
  78. else
  79. while (aStr[aPos] in ['0'..'9','.']) and (aPos <= ord(aStr[0])) do
  80. begin
  81. ret:=ret + aStr[aPos];
  82. inc(aPos);
  83. end;
  84. while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
  85. GetToken:=ret;
  86. end;
  87. {------------------------------}
  88. Function CreateTree(aInp:string):pTree;
  89. var
  90. operations : string;
  91. token : string;
  92. opPos,sPos : byte;
  93. LastOprtn : Boolean;
  94. retcode : integer;
  95. TreeStack : stack;
  96. NewEl : stack;
  97. begin
  98. sPos:=1;
  99. operations[0] := #255;
  100. LastOprtn := true;
  101. TreeStack := nil;
  102. opPos := 0;
  103. while sPos <= ord(aInp[0]) do
  104. begin
  105. Token := GetToken(aInp,sPos);
  106. if Token[1] in Deyst then
  107. begin
  108. if Token[1] <> '(' then
  109. if LastOprtn then
  110. begin
  111. WriteLn('Error in input: ',aInp);
  112. WriteLn('Expected operation at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
  113. Halt(236);
  114. end
  115. else
  116. while (opPos > 0) and (GetPrior(Token[1]) < GetPrior(operations[opPos])) do
  117. begin
  118. CreateBranch(TreeStack,operations[opPos]);
  119. dec(opPos);
  120. end;
  121. if Token[1] <> ')' then
  122. begin
  123. inc(opPos);
  124. operations[opPos] := Token[1];
  125. LastOprtn := true;
  126. end
  127. else
  128. Dec(opPos);
  129. end
  130. else
  131. begin
  132. if not LastOprtn then
  133. begin
  134. WriteLn('Error in input: ',aInp);
  135. WriteLn('Expected operand at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
  136. Halt(236);
  137. end;
  138. New(NewEl);
  139. NewEl^.n := TreeStack;
  140. new(NewEl^.t);
  141. with NewEl^.t^ do
  142. begin
  143. left:=nil;
  144. right:=nil;
  145. Val(Token,operand,retcode);
  146. operation := ' ';
  147. if retcode <> 0 then
  148. begin
  149. WriteLn('Error in input: ',aInp);
  150. WriteLn('in position ',sPos-Length(Token));
  151. Halt(255);
  152. end;
  153. end;
  154. TreeStack := NewEl;
  155. LastOprtn := False;
  156. end;
  157. end;
  158. while opPos > 0 do
  159. begin
  160. CreateBranch(TreeStack,operations[opPos]);
  161. dec(opPos);
  162. end;
  163. CreateTree := TreeStack^.t;
  164. Dispose(TreeStack);
  165. end;
  166. {------=-=-=-=--==-=-=-=--=--==--=}
  167. Procedure ToPostfix(aT:pTree;var aOut:string);
  168. var
  169. aStr : string[13];
  170. begin
  171. if aT = nil then exit;
  172. ToPostfix(aT^.Left,aOut);
  173. ToPostfix(aT^.Right,aOut);
  174. if aT^.Operation = ' ' then
  175. begin
  176. Str(aT^.operand:0:0,aStr);
  177. aOut:=aOut+aStr+' ';
  178. end
  179. else
  180. aOut:=aOut+aT^.Operation+' ';
  181. end;
  182. {-----------------------}
  183. Function aInb(a,b:real):real;
  184. begin
  185. if a > 0 then
  186. aInb:=Exp(b*Ln(a))
  187. else
  188. aInb:=0;
  189. end;
  190. {-----------------------}
  191. Function CalculateTree(aT: pTree):real;
  192. begin
  193. if aT=nil then exit;
  194. Case aT^.Operation of
  195. ' ': CalculateTree:=aT^.Operand;
  196. '+': CalculateTree:=CalculateTree(aT^.Left) + CalculateTree(aT^.Right);
  197. '-': CalculateTree:=CalculateTree(aT^.Left) - CalculateTree(aT^.Right);
  198. '*': CalculateTree:=CalculateTree(aT^.Left) * CalculateTree(aT^.Right);
  199. '/': CalculateTree:=CalculateTree(aT^.Left) / CalculateTree(aT^.Right);
  200. '^': CalculateTree:=aInb(CalculateTree(aT^.Left),CalculateTree(aT^.Right));
  201. end;
  202. end;
  203. {-----------------------}
  204. Procedure DisposeTree(aT : pTree);
  205. begin
  206. if aT <> nil then
  207. Begin
  208. DisposeTree(aT^.Left);
  209. DisposeTree(aT^.Right);
  210. Dispose(aT);
  211. end;
  212. end;
  213. {-------}
  214. var
  215. aIn : string;
  216. aOut : string;
  217. Tree :pTree;
  218. begin
  219. Assign(input,'9.txt');
  220. {$I-}
  221. Reset(input);
  222. if IOResult <> 0 then
  223. begin
  224. WriteLn('File 9.txt not found!');
  225. halt(255);
  226. end;
  227. {$I+}
  228. Readln(aIn);
  229. Close(input);
  230. aOut :='';
  231. Tree := CreateTree(aIn);
  232. ToPostfix(Tree,aOut);
  233. Assign(OutPut,'9.out');
  234. Rewrite(OutPut);
  235. WriteLn('Выражение в постфикс. форме: ',aOut);
  236. WriteLn('Результат: ',CalculateTree(Tree):0:3);
  237. Close(output);
  238. DisposeTree(Tree);
  239. end.