Skip to content

Instantly share code, notes, and snippets.

@dkomanov
Forked from AlexanderVNikitin/gist:3796396
Created September 27, 2012 20:56
Show Gist options
  • Save dkomanov/3796414 to your computer and use it in GitHub Desktop.
Save dkomanov/3796414 to your computer and use it in GitHub Desktop.
Java calculator 2.0.
package ru.mipt;
import java.util.ArrayList;
// Такой комментарий надо либо удалять, либо изменять на осмысленный.
/**
* Created by IntelliJ IDEA.
* User: asus
* Date: 22.09.12
* Time: 11:38
* To change this template use File | Settings | File Templates.
*/
class SuperLex {
Lexem l;
int value;
// перенос строки
public SuperLex(Lexem l1, int value1) {
this.l = l1;
this.value = value1;
}
}
// два пробела
enum Lexem {
// полезно переносить элементы перечисления (для читаемости)
// OPENSC/CLOSESC - sc - это, видимо, скобка (bracket)
NUMBER, PLUS, MINUS, MULT, DIVISION, OPENSC, CLOSESC;
}
public class Calculator {
private static int ind = 0;
static ArrayList<SuperLex> parseLex(String s) {
ArrayList<SuperLex> result = new ArrayList<SuperLex>(0);
int i = 0;
int n = s.length();
while (i < n) {
while (i < n && Character.isSpaceChar(s.charAt(i))) {
++ i;
}
// тут в цикле несколько раз вызывается chatAt(i). Желательно в
// локальную переменную добавить.
if (s.charAt(i) == '+') {
SuperLex tmp = new SuperLex(Lexem.PLUS, 0);
result.add(tmp);
++ i;
// вместо continue в каждом if можно использовать else if
continue;
}
if (s.charAt(i) == '-') {
SuperLex tmp = new SuperLex(Lexem.MINUS, 0);
result.add(tmp);
++ i;
continue;
}
if (s.charAt(i) == '*') {
SuperLex tmp = new SuperLex(Lexem.MULT, 0);
result.add(tmp);
++ i;
continue;
}
if (s.charAt(i) == '/') {
SuperLex tmp = new SuperLex(Lexem.DIVISION, 0);
result.add(tmp);
++ i;
continue;
}
if (s.charAt(i) == '(') {
SuperLex tmp = new SuperLex(Lexem.OPENSC, 0);
result.add(tmp);
++ i;
continue;
}
if (s.charAt(i) == ')') {
SuperLex tmp = new SuperLex(Lexem.CLOSESC, 0);
result.add(tmp);
++ i;
continue;
}
if (Character.isDigit(s.charAt(i))) {
int st = 1;
int resultVal = 0;
while (i < n && Character.isDigit(s.charAt(i))) {
resultVal *= 10;
resultVal += (int)s.charAt(i) - (int)'0';
++ i;
}
// вместо этого попробуй использовать Integer.parseInt
SuperLex tmp = new SuperLex(Lexem.NUMBER, resultVal);
result.add(tmp);
}
}
return result;
}
public static int expr(ArrayList<SuperLex> sample) throws Exception {
int n = sample.size();
// Удаляй, пожалуйста, неиспользуемый код.
//System.out.println("Expr " + ind);
int cur = summand(sample);
//System.out.println("|" + ind + "|");
// строка длиннее 80 символов
while (ind < n && (sample.get(ind).l.equals(Lexem.PLUS) || sample.get(ind).l.equals(Lexem.MINUS))) {
if (sample.get(ind).l.equals(Lexem.PLUS)) {
++ ind;
cur += summand(sample);
} else {
++ ind;
cur -= summand(sample);
}
}
return cur;
}
public static int summand(ArrayList<SuperLex> sample) throws Exception {
int n = sample.size();
//System.out.println("Summand " + ind);
int cur = factor(sample);
//System.out.println(ind);
while (ind < n && (sample.get(ind).l.equals(Lexem.MULT) || sample.get(ind).l.equals(Lexem.DIVISION))) {
if (sample.get(ind).l.equals(Lexem.MULT)) {
++ ind;
cur *= factor(sample);
} else {
if (sample.get(ind).l.equals(Lexem.DIVISION)) {
++ ind;
cur /= factor(sample);
}
}
}
return cur;
}
public static int factor(ArrayList<SuperLex> sample) throws Exception {
//System.out.println("Factor " + ind);
SuperLex cur = sample.get(ind);
int result = 0;
switch(cur.l) {
case NUMBER:
result = cur.value;
++ ind;
break;
case OPENSC:
++ ind;
result = expr(sample);
if (sample.get(ind).l.equals(Lexem.CLOSESC)) {
++ ind;
} else {
throw new Exception("Incorrect Expression");
}
break;
default:
throw new Exception("Incorrect Expression");
}
return result;
}
public static void main(String args[]) throws Exception {
int n = args.length;
int res = 0;
if (n == 0) {
// Вызов программы без аргументов падает с исключением.
// Это не очень дружественно пользователю.
throw new Exception("You have to write at least 1 param");
}
for (int i = 0; i < n; ++ i) {
String s = args[i];
ind = 0;
//System.out.println("|" + s + "|");
ArrayList<SuperLex> result = parseLex(s);
/*for (int j = 0; j < result.size(); ++ j) {
System.out.println(result.get(j).l + "======" + result.get(j).value);
} */
res = expr(result);
System.out.println(res);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment