EQuations.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. {
  2. „®áâã¯­ë¥ ®¯¥à æ¨¨:
  3. +-*/ - áâ ­¤ àâ­®
  4. ^ - ¢®§¢¥¤¥­¨¥ ¢ á⥯¥­ì
  5. «î¡ë¥ ᨬ¢®«ë - ¢®á¯à¨­¨¬ îâáï ª ª •
  6. }
  7. const
  8. deyst = ['+','-','*','/','^',')','('];
  9. type
  10. pTree = ^tTree;
  11. tTree = record
  12. operand : real;
  13. operation : char;
  14. left : pTree;
  15. right : pTree;
  16. end;
  17. stack = ^tstack;
  18. tstack = record
  19. t : pTree;
  20. n : stack;
  21. end;
  22. {------------------------------}
  23. Procedure CreateBranch(var aStack : stack;aCurOper : char);
  24. var
  25. aN : pTree;
  26. aL : stack;
  27. begin
  28. if (aStack = nil) or
  29. ((aStack^.n = nil) AND NOT (aCurOper IN ['~','c','s','l','t','o'])) then
  30. begin
  31. WriteLn('Error in operators');
  32. Halt(255);
  33. end;
  34. New(aN);
  35. with aN^ do
  36. begin
  37. operation := aCurOper;
  38. Right:=aStack^.t;
  39. aL := aStack;
  40. aStack := aStack^.n;
  41. Dispose(aL);
  42. if not (aCurOper in ['~','c','s','l','t','o']) then
  43. begin
  44. Left :=aStack^.t;
  45. aL:=aStack;
  46. aStack := aStack^.n;
  47. Dispose(aL);
  48. end
  49. else Left:=nil;
  50. aL:=aStack;
  51. end;
  52. New(aStack);
  53. aStack^.n := aL;
  54. aStack^.t := aN;
  55. end;
  56. {------------------------------}
  57. function GetPrior(a:char):integer;
  58. begin
  59. case a of
  60. '(':GetPrior:=5;
  61. ')':GetPrior:=5;
  62. '~':GetPrior:=100;
  63. '+':GetPrior:=10;
  64. '-':GetPrior:=12;
  65. '*':GetPrior:=20;
  66. '/':GetPrior:=22;
  67. '^':GetPrior:=30;
  68. else begin
  69. WriteLN('Sorry, undefined operation, ''',a,'''');
  70. end;
  71. end;
  72. end;
  73. {------------------------------}
  74. function GetToken(var aStr:string;var aPos:byte):string;
  75. var
  76. ret:string;
  77. begin
  78. ret:='';
  79. while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
  80. if aStr[aPos] in Deyst then
  81. begin
  82. ret := aStr[aPos];
  83. inc(aPos)
  84. end
  85. else
  86. if aStr[aPos] in ['0'..'9','.'] then
  87. while (aStr[aPos] in ['0'..'9','.']) and (aPos <= ord(aStr[0])) do
  88. begin
  89. ret:=ret + aStr[aPos];
  90. inc(aPos);
  91. end
  92. else
  93. begin
  94. ret := aStr[aPos];
  95. inc(aPos);
  96. end;
  97. while (aStr[aPos] = ' ') and (aPos <= ord(aStr[0])) do inc(aPos);
  98. GetToken:=ret;
  99. end;
  100. {------------------------------}
  101. Function CreateTree(aInp:string):pTree;
  102. var
  103. operations : string;
  104. token : string;
  105. opPos,sPos : byte;
  106. LastOprtn : Boolean;
  107. retcode : integer;
  108. TreeStack : stack;
  109. NewEl : stack;
  110. begin
  111. sPos:=1;
  112. operations[0] := #255;
  113. LastOprtn := true;
  114. TreeStack := nil;
  115. opPos := 0;
  116. while sPos <= ord(aInp[0]) do
  117. begin
  118. Token := GetToken(aInp,sPos);
  119. if Token[1] in Deyst then
  120. begin
  121. if Token[1] = '-' then
  122. begin
  123. if (sPos=2) OR (aInp[sPos-2] = '(') then
  124. begin
  125. inc(opPos);
  126. operations[opPos] := '~';
  127. LastOprtn := true;
  128. end;
  129. end
  130. else
  131. begin
  132. if Token[1] <> '(' then
  133. if LastOprtn then
  134. begin
  135. WriteLn('Error in input: ',aInp);
  136. WriteLn('Expected operation at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
  137. Halt(236);
  138. end
  139. else
  140. while (opPos > 0) and (GetPrior(Token[1]) < GetPrior(operations[opPos])) do
  141. begin
  142. CreateBranch(TreeStack,operations[opPos]);
  143. dec(opPos);
  144. end;
  145. if Token[1] <> ')' then
  146. begin
  147. inc(opPos);
  148. operations[opPos] := Token[1];
  149. LastOprtn := true;
  150. end
  151. else
  152. Dec(opPos);
  153. end
  154. end
  155. else
  156. begin
  157. if not LastOprtn then
  158. begin
  159. WriteLn('Error in input: ',aInp);
  160. WriteLn('Expected operand at position near ''',Copy(aInp,sPos-Length(Token),5),'''');
  161. Halt(236);
  162. end;
  163. New(NewEl);
  164. NewEl^.n := TreeStack;
  165. new(NewEl^.t);
  166. with NewEl^.t^ do
  167. begin
  168. left:=nil;
  169. right:=nil;
  170. if Token[1] IN ['0'..'9','.'] then
  171. begin
  172. Val(Token,operand,retcode);
  173. operation := ' ';
  174. end
  175. else
  176. operation := 'x';
  177. if retcode <> 0 then
  178. begin
  179. WriteLn('Error in input: ',aInp);
  180. WriteLn('in position ',sPos-Length(Token));
  181. Halt(255);
  182. end;
  183. end;
  184. TreeStack := NewEl;
  185. LastOprtn := False;
  186. end;
  187. end;
  188. while opPos > 0 do
  189. begin
  190. CreateBranch(TreeStack,operations[opPos]);
  191. dec(opPos);
  192. end;
  193. CreateTree := TreeStack^.t;
  194. Dispose(TreeStack);
  195. end;
  196. {------=-=-=-=--==-=-=-=--=--==--=}
  197. Procedure ToPostfix(aT:pTree;var aOut:string);
  198. var
  199. aStr : string[13];
  200. begin
  201. if aT = nil then exit;
  202. ToPostfix(aT^.Left,aOut);
  203. ToPostfix(aT^.Right,aOut);
  204. if aT^.Operation = ' ' then
  205. begin
  206. Str(aT^.operand:0:1,aStr);
  207. aOut:=aOut+aStr+' ';
  208. end
  209. else
  210. aOut:=aOut+aT^.Operation+' ';
  211. end;
  212. {-----------------------}
  213. Function aInb(a,b:real):real;
  214. begin
  215. if a > 0 then
  216. aInb:=Exp(b*Ln(a))
  217. else
  218. aInb:=0;
  219. end;
  220. {-----------------------}
  221. Function CalculateTree(aT: pTree; aX:real):real;
  222. begin
  223. if aT=nil then exit;
  224. Case aT^.Operation of
  225. ' ': CalculateTree:=aT^.Operand;
  226. 'x': CalculateTree:=aX;
  227. '~': CalculateTree:=-CalculateTree(aT^.Right,aX);
  228. '+': CalculateTree:=CalculateTree(aT^.Left,aX) + CalculateTree(aT^.Right,aX);
  229. '-': CalculateTree:=CalculateTree(aT^.Left,aX) - CalculateTree(aT^.Right,aX);
  230. '*': CalculateTree:=CalculateTree(aT^.Left,aX) * CalculateTree(aT^.Right,aX);
  231. '/': CalculateTree:=CalculateTree(aT^.Left,aX) / CalculateTree(aT^.Right,aX);
  232. '^': CalculateTree:=aInb(CalculateTree(aT^.Left,aX),CalculateTree(aT^.Right,aX));
  233. end;
  234. end;
  235. {-----------------------}
  236. Procedure DisposeTree(aT : pTree);
  237. begin
  238. if aT <> nil then
  239. Begin
  240. DisposeTree(aT^.Left);
  241. if aT^.Right <> nil then DisposeTree(aT^.Right);
  242. Dispose(aT);
  243. end;
  244. end;
  245. {-------}
  246. var
  247. aIn : string;
  248. aOut : string;
  249. Tree :pTree;
  250. begin
  251. aIn := '-3*(-x)';
  252. aOut :='';
  253. Tree := CreateTree(aIn);
  254. ToPostfix(Tree,aOut);
  255. { Assign(OutPut,'9.out');
  256. Rewrite(OutPut);}
  257. WriteLn('‚ëà ¦¥­¨¥: ',aIn);
  258. WriteLn('‚ëà ¦¥­¨¥ ¢ ¯®áâ䨪á. ä®à¬¥: ',aOut);
  259. WriteLn('�¥§ã«ìâ â: ',CalculateTree(Tree, 1):0:3 );
  260. Close(output);
  261. DisposeTree(Tree);
  262. end.