fork download
  1. import java.io.*;
  2. import java.util.*;
  3. import java.lang.*;
  4.  
  5.  
  6. final class Expr {
  7. private final static long LONG_MIN = Long.MIN_VALUE / 10L;
  8. private final static long LONG_MAX = Long.MAX_VALUE / 10L;
  9.  
  10. public static long Calc(String s) throws Exception {
  11. s = s.replaceAll("\\s+", ""); // удалим пробелы, '\n', '\t'...
  12.  
  13. if(s.length() == 0)
  14. throw new IllegalArgumentException("Строка пуста!");
  15. if(! is_rules(s))
  16. throw new IllegalArgumentException("Ошибка в расстоновки скобок!");
  17.  
  18. int[] index = {0};
  19. return SubExpr(s, index);
  20. }
  21.  
  22.  
  23. private static long SubExpr(String s, int[] index){
  24. boolean neg, loop;
  25. long val, num;
  26. Stack<Character> sops = new Stack<Character>();
  27. Stack<Long> sval = new Stack<Long>();
  28.  
  29. neg = false;
  30. loop = true;
  31.  
  32. for(int i = index[0]; i < s.length(); ){
  33.  
  34. switch(s.charAt(i)){
  35. case '+':
  36. case '/':
  37. case '*':
  38. sops.push(s.charAt(i));
  39. ++i;
  40. break;
  41. case '-':
  42.  
  43. if((i == 0) || ((i > 0) && is_math(s.charAt(i - 1)))){
  44. neg = true;
  45. ++i;
  46. break;
  47. }
  48. sops.push(s.charAt(i));
  49. ++i;
  50.  
  51. break;
  52. case '(':
  53.  
  54. index[0] = i + 1;
  55. val = SubExpr(s, index);
  56. i = index[0];
  57.  
  58. if(neg)
  59. val = 0L - val;
  60. neg = false;
  61.  
  62. sval.push(val);
  63. calc_muldiv(sval, sops);
  64. break;
  65. case ')':
  66. index[0] = i + 1;
  67. loop = false;
  68. break;
  69. default:
  70.  
  71. if(! Character.isDigit(s.charAt(i)))
  72. throw new NumberFormatException("Неизвестный символ!");
  73.  
  74. index[0] = i;
  75. val = ToLong(s, index);
  76. i = index[0];
  77.  
  78. if(neg)
  79. val = 0L - val;
  80. neg = false;
  81.  
  82. sval.push(val);
  83. calc_muldiv(sval, sops);
  84. break;
  85. }
  86.  
  87. if(! loop)
  88. break;
  89. }
  90.  
  91. if(sval.size() == 0)
  92. throw new IllegalArgumentException("Ошибка синтаксиса!");
  93.  
  94. num = sval.get(0);
  95. sval.remove(0);
  96.  
  97. for(int i = 0; (i < sops.size()) && (i < sval.size()); ++i){
  98. switch(sops.get(i)){
  99. case '+':
  100. num += sval.get(i);
  101. break;
  102. case '-':
  103. num -= sval.get(i);
  104. break;
  105. }
  106. }
  107. sops.clear();
  108. sval.clear();
  109. sops = null;
  110. sval = null;
  111. return num;
  112. }
  113.  
  114. //приоритетные операции: умножение, деление
  115. private static void calc_muldiv(Stack<Long> sval, Stack<Character> sops){
  116. long val;
  117. char ch;
  118.  
  119. while(! sops.isEmpty()){
  120. ch = sops.peek();
  121. if((ch == '+') || (ch == '-'))
  122. break;
  123.  
  124. val = sval.peek();
  125. sval.pop();
  126. if(sval.size() == 0)
  127. throw new IllegalArgumentException("Ошибка синтаксиса!");
  128.  
  129. if(ch == '*')
  130. sval.set(sval.size() - 1, sval.peek() * val);
  131. else if(ch == '/'){
  132. if(val == 0L)
  133. throw new ArithmeticException("Деление на нуль!");
  134. sval.set(sval.size() - 1, sval.peek() / val);
  135. }
  136. sops.pop();
  137. }
  138. }
  139.  
  140. // конвертирование числа из строки
  141. private static long ToLong(String s, int[] index){
  142. long n = 0L;
  143. int i;
  144.  
  145. for(i = index[0]; i < s.length(); ++i){
  146. if(Character.isDigit(s.charAt(i))){
  147.  
  148. if(n > LONG_MAX || n < LONG_MIN)
  149. throw new NumberFormatException("Переполнение числа!");
  150.  
  151. n = n * 10L + (long) (s.charAt(i) - '0');
  152. } else
  153. break;
  154. }
  155. index[0] = i;
  156. return n;
  157. }
  158.  
  159. //проверка правильности расстановки скобочных выражений
  160. private static boolean is_rules(String s){
  161. int n = 0;
  162. for(int i = 0; i < s.length(); ++i){
  163. if(s.charAt(i) == '(')
  164. ++n;
  165. else if(s.charAt(i) == ')')
  166. --n;
  167. }
  168. return (n == 0);
  169. }
  170.  
  171. private static boolean is_math(char ch){
  172. return (ch == '+' || ch == '-' ||
  173. ch == '*' || ch == '/' || ch == '(');
  174. }
  175. }
  176.  
  177.  
  178. class Project {
  179. public static void main(String[] args) {
  180. String s = "-1-(-7*-7-(-(-(-(10-2)/2*3+1)/4)+2)+2/(1+(-(-2)+3+(-4))+5))/10";
  181. long jvm = -1-(-7*-7-(-(-(-(10-2)/2*3+1)/4)+2)+2/(1+(-(-2)+3+(-4))+5))/10;
  182. try {
  183. long res = Expr.Calc(s);
  184. System.out.println("парсер: " + res);
  185. System.out.println("static: " + jvm);
  186. } catch(Exception e){
  187. System.err.println(e.getMessage());
  188. }
  189. }
  190. }
Success #stdin #stdout 0.09s 320256KB
stdin
Standard input is empty
stdout
парсер: -5
static: -5