public class Calculator {
public static void main ( String [ ] args) {
Scanner in = new Scanner ( System . in) ;
while ( true ) {
System . out. println ( "please enter expression : " ) ;
String expression = in. nextLine ( ) ;
String exprAfterTransfer = expressionToComputerOperators ( expression) ;
boolean trueExpression = isTrueExpression ( exprAfterTransfer) ;
if ( trueExpression) {
List list = addToList ( exprAfterTransfer) ;
List postExpression = getPostExpression ( list) ;
double result = getResultByUsePostExpression ( postExpression) ;
System . out. println ( expression + " = " + result) ;
} else {
System . err. println ( "{ " + expression + " } is error math expression!" ) ;
}
}
}
public static double getResultByUsePostExpression ( List < String > list) {
Stack < String > stack = new Stack < > ( ) ;
for ( int i = 0 ; i < list. size ( ) ; i++ ) {
if ( list. get ( i) . matches ( "\\d+\\.{0,1}\\d*" ) ) {
stack. push ( list. get ( i) ) ;
} else {
double num1 = Double . parseDouble ( stack. pop ( ) ) ;
double num2 = Double . parseDouble ( stack. pop ( ) ) ;
double result = 0 ;
switch ( list. get ( i) ) {
case "+" :
result = num2 + num1;
break ;
case "-" :
result = num2 - num1;
break ;
case "*" :
result = num2 * num1;
break ;
case "/" :
result = num2 / num1;
break ;
}
stack. push ( "" + result) ;
}
}
return Double . parseDouble ( stack. pop ( ) ) ;
}
public static List getPostExpression ( List < String > list) {
Stack < String > operators = new Stack < > ( ) ;
Stack < String > median = new Stack < > ( ) ;
List < String > list1 = new ArrayList < > ( ) ;
for ( int i = 0 ; i < list. size ( ) ; i++ ) {
while ( true ) {
if ( list. get ( i) . matches ( "\\d+\\.{0,1}\\d*" ) ) {
median. push ( list. get ( i) ) ;
break ;
} else if ( isOperator ( list. get ( i) . charAt ( 0 ) ) ) {
if ( operators. empty ( ) || operators. peek ( ) . equals ( "(" ) ) {
operators. push ( list. get ( i) ) ;
break ;
} else if ( getPriority ( list. get ( i) ) > getPriority ( operators. peek ( ) ) ) {
operators. push ( list. get ( i) ) ;
break ;
} else {
median. push ( operators. pop ( ) ) ;
}
} else if ( isBracket ( list. get ( i) . charAt ( 0 ) ) ) {
if ( list. get ( i) . equals ( "(" ) ) {
operators. push ( list. get ( i) ) ;
break ;
} else {
while ( ! operators. empty ( ) && ! operators. peek ( ) . equals ( "(" ) ) {
median. push ( operators. pop ( ) ) ;
}
if ( ! operators. empty ( ) ) {
operators. pop ( ) ;
}
break ;
}
}
}
}
while ( ! operators. empty ( ) ) {
median. push ( operators. pop ( ) ) ;
}
while ( ! median. empty ( ) ) {
list1. add ( median. pop ( ) ) ;
}
Collections . reverse ( list1) ;
return list1;
}
public static int getPriority ( String str) {
if ( str. equals ( "+" ) || str. equals ( "-" ) ) {
return 1 ;
} else if ( str. equals ( "*" ) || str. equals ( "/" ) ) {
return 2 ;
} else {
return 0 ;
}
}
public static double getResultByUsePreExpression ( List < String > list) {
Stack < String > stack = new Stack < > ( ) ;
for ( int i = list. size ( ) - 1 ; i >= 0 ; i-- ) {
if ( list. get ( i) . matches ( "\\d+\\.{0,1}\\d*" ) ) {
stack. push ( list. get ( i) ) ;
} else {
if ( isOperator ( list. get ( i) . charAt ( 0 ) ) ) {
double num1 = Double . parseDouble ( stack. pop ( ) ) ;
double num2 = Double . parseDouble ( stack. pop ( ) ) ;
double result = 0 ;
switch ( list. get ( i) ) {
case "+" :
result = num1 + num2;
break ;
case "-" :
result = num1 - num2;
break ;
case "*" :
result = num1 * num2;
break ;
case "/" :
result = num1 / num2;
break ;
}
stack. push ( "" + result) ;
}
}
}
return Double . parseDouble ( stack. pop ( ) ) ;
}
public static List getPreExpression ( List < String > list) {
List < String > list1 = new ArrayList < > ( ) ;
Stack < String > operators = new Stack < > ( ) ;
Stack < String > median = new Stack < > ( ) ;
for ( int i = list. size ( ) - 1 ; i >= 0 ; i-- ) {
String value = list. get ( i) ;
while ( true ) {
if ( value. matches ( "\\d+\\.{0,1}\\d*" ) ) {
median. push ( value) ;
break ;
} else if ( isOperator ( value. charAt ( 0 ) ) ) {
if ( operators. empty ( ) || operators. peek ( ) . equals ( ")" ) ) {
operators. push ( value) ;
break ;
} else if ( getPriority ( value) >= getPriority ( operators. peek ( ) ) ) {
operators. push ( value) ;
break ;
} else {
median. push ( operators. pop ( ) ) ;
}
} else if ( isBracket ( value. charAt ( 0 ) ) ) {
if ( value. equals ( ")" ) ) {
operators. push ( value) ;
break ;
} else {
while ( ! operators. empty ( ) && ! operators. peek ( ) . equals ( ")" ) ) {
median. push ( operators. pop ( ) ) ;
}
if ( ! operators. empty ( ) && operators. peek ( ) . equals ( ")" ) ) {
operators. pop ( ) ;
}
break ;
}
}
}
}
while ( ! operators. empty ( ) ) {
median. push ( operators. pop ( ) ) ;
}
while ( ! median. empty ( ) ) {
list1. add ( median. pop ( ) ) ;
}
return list1;
}
public static List addToList ( String expression) {
List < String > list = new ArrayList < > ( ) ;
int i = 0 ;
do {
char ch = expression. charAt ( i) ;
String str = "" ;
if ( ch == ' ' ) {
i++ ;
} else {
if ( isOperator ( ch) || isBracket ( ch) ) {
list. add ( str += ch) ;
i++ ;
} else if ( isNumber ( ch) ) {
str += ch;
i++ ;
while ( i < expression. length ( ) && ( isNumber ( expression. charAt ( i) ) || isPoint ( expression. charAt ( i) ) ) ) {
str += expression. charAt ( i) ;
i++ ;
}
list. add ( str) ;
}
}
} while ( i < expression. length ( ) ) ;
return list;
}
public static int getPreIndexOfNotBlankSpace ( String expression, int i) {
if ( i == 0 ) {
return 0 ;
} else if ( i < 0 || i >= expression. length ( ) ) {
throw new RuntimeException ( "error" ) ;
} else {
i-- ;
while ( expression. charAt ( i) == ' ' ) {
i-- ;
}
return i;
}
}
public static int getNextIndexOfNotBlankSpace ( String expression, int i) {
if ( i == expression. length ( ) - 1 ) {
return expression. length ( ) - 1 ;
} else if ( i < 0 || i >= expression. length ( ) ) {
throw new RuntimeException ( "error" ) ;
} else {
i++ ;
while ( expression. charAt ( i) == ' ' ) {
i++ ;
}
return i;
}
}
public static boolean isTrueExpression ( String expression) {
if ( "" . equals ( expression) || isOperator ( expression. charAt ( 0 ) ) || isOperator ( expression. charAt ( expression. length ( ) - 1 ) ) || isPoint ( expression. charAt ( 0 ) ) || isPoint ( expression. charAt ( expression. length ( ) - 1 ) ) ) {
return false ;
} else {
Stack < Character > stack = new Stack < > ( ) ;
int i = 0 ;
while ( i < expression. length ( ) ) {
char ch = expression. charAt ( i) ;
if ( isNumber ( ch) || isOperator ( ch) || isPoint ( ch) || isBracket ( ch) || ch == ' ' ) {
int pre = getPreIndexOfNotBlankSpace ( expression, i) ;
int next = getNextIndexOfNotBlankSpace ( expression, i) ;
if ( ch == ' ' ) {
if ( isPoint ( expression. charAt ( pre) ) || isPoint ( expression. charAt ( next) ) || ( isNumber ( expression. charAt ( pre) ) ) && isNumber ( expression. charAt ( next) ) || ( isOperator ( expression. charAt ( pre) ) ) && isOperator ( expression. charAt ( next) ) ) {
return false ;
}
}
if ( ch == '(' ) {
if ( isPoint ( expression. charAt ( next) ) || expression. charAt ( next) == '*' || expression. charAt ( next) == '/' || expression. charAt ( next) == ')' ) {
return false ;
}
stack. push ( ch) ;
}
if ( ch == ')' ) {
if ( stack. empty ( ) || ( ! isOperator ( expression. charAt ( next) ) && expression. charAt ( next) != ')' ) ) {
return false ;
} else {
stack. pop ( ) ;
}
}
if ( ch == '/' ) {
if ( expression. charAt ( next) == '0' ) {
return false ;
}
}
if ( isOperator ( ch) ) {
if ( isPoint ( expression. charAt ( pre) ) || isPoint ( expression. charAt ( next) ) || expression. charAt ( next) == ')' || isOperator ( expression. charAt ( next) ) ) {
return false ;
}
}
if ( isPoint ( ch) ) {
if ( ! isNumber ( expression. charAt ( pre) ) || ! isNumber ( expression. charAt ( next) ) ) {
return false ;
}
}
i++ ;
} else {
return false ;
}
}
}
return true ;
}
public static String expressionToComputerOperators ( String expression) {
expression = expression. trim ( ) ;
String str = "" ;
for ( int i = 0 ; i < expression. length ( ) ; i++ ) {
char ch = expression. charAt ( i) ;
if ( ch == '[' || ch == '{' ) {
str += "(" ;
} else if ( ch == ']' || ch == '}' ) {
str += ")" ;
} else if ( ch == '×' ) {
str += '*' ;
} else if ( ch == '÷' ) {
str += "/" ;
} else {
str += ch;
}
}
return str;
}
public static boolean isNumber ( char ch) {
if ( ch >= '0' && ch <= '9' ) {
return true ;
} else {
return false ;
}
}
public static boolean isOperator ( char ch) {
if ( ch == '+' || ch == '-' || ch == '*' || ch == '/' ) {
return true ;
} else {
return false ;
}
}
public static boolean isPoint ( char ch) {
return ch == '.' ;
}
public static boolean isBracket ( char ch) {
return ch == '(' || ch == ')' ;
}
}