STRCALC.PAS 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. const
  2. deyst = ['+','*','/','-','(',')'];
  3. Copers : array [1..6] of char = ('+','-','*','/','(',')');
  4. type
  5. ps = ^el;
  6. el = record
  7. data : integer;
  8. prev : ps;
  9. end;
  10. var
  11. header : ps;
  12. polsk : string;
  13. Procedure MakeD(var num1:integer;num2:integer;dey:char);
  14. begin
  15. case dey of
  16. '+': num1 := num1 + num2;
  17. '-': num1 := num1 - num2;
  18. '*': num1 := num1 * num2;
  19. '/': if num2 <> 0 then num1 := num1 div num2;
  20. end;
  21. end;
  22. Function GetOper(dey:char):integer;
  23. begin
  24. case dey of
  25. '+': GetOper:=1;
  26. '-': GetOper:=2;
  27. '*': GetOper:=3;
  28. '/': GetOper:=4;
  29. '(': GetOper:=5;
  30. ')': GetOper:=6;
  31. end;
  32. end;
  33. Function GetPrior(dey : integer):integer;
  34. begin
  35. case dey of
  36. 1..2: GetPrior:=1;
  37. 3..4: GetPrior:=2;
  38. 5 : GetPrior:=0;
  39. 6 : GetPrior:=3;
  40. end;
  41. end;
  42. Function GetNext(a:string;var pos:byte;done:boolean):string;
  43. var ret : string;
  44. begin
  45. ret := a[pos];
  46. inc(pos);
  47. if not(a[pos-1] in deyst) then
  48. begin
  49. if done then while (a[pos] <> ',') and (pos<>length(a)+1) do
  50. begin
  51. ret := ret + a[pos];
  52. inc(pos);
  53. end
  54. else
  55. while (not(a[pos] in deyst)) and (pos<>length(a)+1) do
  56. begin
  57. ret := ret + a[pos];
  58. inc(pos);
  59. end;
  60. end;
  61. if done then inc(pos);
  62. GetNext := ret;
  63. end;
  64. Procedure PUSH(i:integer;var head:ps);
  65. var ne : ps;
  66. begin
  67. New(ne);
  68. ne^.data := i;
  69. ne^.prev := head;
  70. head := ne;
  71. end;
  72. Function POP(var head:ps):integer;
  73. var ret:integer;newhead:ps;
  74. begin
  75. ret := head^.data;
  76. newhead := head^.prev;
  77. Dispose(head);
  78. head := newhead;
  79. POP := ret;
  80. end;
  81. Function MakePol(inp:string):string;
  82. Var
  83. datas : ps;
  84. opers : ps;
  85. pos : byte;
  86. cur : string;
  87. outp : string;
  88. curout : string;
  89. num,
  90. code,
  91. oper : integer;
  92. Procedure PopAll;
  93. begin
  94. While (datas^.prev <>nil) and (datas^.prev^.prev <> nil) and (opers^.prev <> nil) do
  95. begin
  96. str(POP(datas),curout);
  97. outp := outp + curout + ',';
  98. str(POP(datas),curout);
  99. outp := outp + curout + ',';
  100. outp := outp+Copers[POP(opers)]+',';
  101. if outp[length(outp)-2] in ['(',')'] then delete(outp,length(outp)-2,2);
  102. end;
  103. While datas^.prev <> nil do
  104. begin
  105. str(POP(datas),curout);
  106. outp := outp + curout + ',';
  107. end;
  108. While opers^.prev <> nil do
  109. begin
  110. outp := outp+Copers[POP(opers)]+',';
  111. if outp[length(outp)-1] in ['(',')'] then delete(outp,length(outp)-1,2);
  112. end;
  113. end;
  114. Begin
  115. New(Datas);
  116. New(opers);
  117. OutP := '';
  118. datas^.prev := nil;
  119. opers^.prev := nil;
  120. opers^.data := 0;
  121. pos := 1;
  122. while pos <> length(inp)+1 do
  123. begin
  124. cur := GetNext(inp,pos,false);
  125. if cur[length(cur)] in deyst then
  126. begin
  127. oper := GetOper(cur[1]);
  128. if opers^.prev <> nil then
  129. begin
  130. if oper = 6 then PopAll else begin
  131. while (GetPrior(opers^.data) >= GetPrior(oper)) and (datas^.prev<>nil) do
  132. begin
  133. str(POP(datas),curout);
  134. outp := outp + curout + ',';
  135. if length(outp) = length(curout)+1 then
  136. begin
  137. str(POP(datas),curout);
  138. outp := outp + curout + ',';
  139. end;
  140. outp := outp+Copers[POP(opers)]+',';
  141. if outp[length(outp)-1] in ['(',')'] then
  142. delete(outp,length(outp)-1,2);
  143. end;
  144. PUSH(oper,opers)
  145. end;
  146. end
  147. else
  148. PUSH(oper,opers);
  149. end
  150. else
  151. begin
  152. val(cur,num,code);
  153. PUSH(num,datas);
  154. end;
  155. end;
  156. PopAll;
  157. MakePol := outp;
  158. end;{MakePol}
  159. {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  160. Procedure Calculate(polsk:string;var header : ps);
  161. Var
  162. this : string;
  163. pos1 : byte;
  164. num1,
  165. num2 : integer;
  166. begin
  167. pos1:=1;
  168. While pos1 <> length(polsk)+1 do
  169. begin
  170. this := getNext(polsk,pos1,true);
  171. if this[length(this)] in deyst then
  172. begin
  173. num1 := POP(header);
  174. num2 := POP(header);
  175. makeD(num1,num2,this[1]);
  176. PUSH(num1,header);
  177. end
  178. else
  179. begin
  180. val(this,num1,num2);
  181. PUSH(num1,header);
  182. end;
  183. end;
  184. end;
  185. {--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--}
  186. Var
  187. FIN : text;
  188. FOUT : text;
  189. inpstr: string;
  190. begin
  191. Assign(FIN,'input.txt');
  192. Reset(FIN);
  193. ReadLn(FIN,InpStr);
  194. Close(FIN);
  195. Polsk := MakePol(InpStr);
  196. { polsk := '8,3,*,5,+,9,+,';}
  197. header^.prev := nil;
  198. Calculate(polsk,header);
  199. Assign(FOUT,'output.txt');
  200. Rewrite(Fout);
  201. WriteLN(FOUT,POP(header));
  202. Close(Fout);
  203. end.