代码实现
package calculator;
import java. util. ArrayList;
public class Calculator {
static ArrayList< String> factor= new ArrayList < String> ( ) ;
static BinaryTree root;
public static void main ( String[ ] args) {
Function f= new Function ( "f(a,b)=a^b" ) ;
Operator. loadFunctionOperator ( f) ;
Function sqrt= new Function ( "g(a)=a^2+a+1" ) ;
Operator. loadFunctionOperator ( sqrt) ;
Calculator cal= new Calculator ( "-1+f(2+1,3)+sqrt(2)" ) ;
}
public static double get ( String str) {
division ( str) ;
factor. forEach ( e- > { System. out. print ( e+ " " ) ; } ) ;
ArrayList< BinaryTree> olist = Objectification ( factor) ;
root= Linker. linkAll ( olist) ;
return ( ( AvailableValue) root) . getValue ( ) ;
}
public Calculator ( String str) {
division ( str) ;
factor. forEach ( e- > {
System. out. print ( e+ " " ) ;
} ) ;
System. out. println ( ) ;
ArrayList< BinaryTree> olist = Objectification ( factor) ;
root= Linker. linkAll ( olist) ;
show ( root) ;
System. out. println ( ) ;
System. out. println ( ( ( AvailableValue) root) . getValue ( ) ) ;
}
public static ArrayList< BinaryTree> Objectification ( ArrayList< String> slist) {
ArrayList< BinaryTree> alist= new ArrayList < BinaryTree> ( ) ;
slist. forEach ( e- > {
if ( Numerical. isNumerical ( e) ) {
alist. add ( new Numerical ( e) ) ;
} else if ( Operator. isOperator ( e) ) {
alist. add ( Operator. createOpertor ( e) ) ;
}
} ) ;
return alist;
}
public static ArrayList< String> division ( String str) {
int last= 0 , now = 0 ;
for ( ; now< str. length ( ) ; ) {
if ( Operator. isOperator ( str. charAt ( now) + "" ) ) {
if ( last== now) {
factor. add ( str. substring ( last, now+ 1 ) ) ;
last++ ;
} else if ( last< now) {
factor. add ( str. substring ( last, now) ) ;
last= now;
factor. add ( str. substring ( last, now+ 1 ) ) ;
last++ ;
}
}
now++ ;
}
if ( last< str. length ( ) ) {
factor. add ( str. substring ( last, str. length ( ) ) ) ;
}
for ( int i= 1 ; i< factor. size ( ) - 1 ; i++ ) {
if ( factor. get ( i) . equals ( "(" ) ) {
if ( ( ! Operator. isOperator ( factor. get ( i- 1 ) )
|| factor. get ( i- 1 ) . equals ( ")" ) ) ) {
factor. add ( i, "*" ) ;
}
} else if ( factor. get ( i) . equals ( ")" ) ) {
if ( ( ! Operator. isOperator ( factor. get ( i+ 1 ) )
|| factor. get ( i+ 1 ) . equals ( "(" ) ) ) {
factor. add ( i+ 1 , "*" ) ;
}
}
}
return factor;
}
public void show ( BinaryTree node) {
if ( node== null ) return ;
if ( node instanceof Operator ) {
if ( node instanceof FunOperator ) {
String string = " " + ( ( Operator) node) . getOperator ( ) + "( " ;
for ( Double v : ( ( FunOperator) node) . valueList) {
string+= v+ " , " ;
}
if ( string. charAt ( string. length ( ) - 2 ) == ',' )
string= string. substring ( 0 , string. length ( ) - 2 ) ;
string+= ")" ;
System. out. print ( string) ;
} else {
System. out. print ( " ( " ) ;
show ( node. getLeft ( ) ) ;
System. out. print ( ( ( Operator) node) . getOperator ( ) ) ;
show ( node. getRight ( ) ) ;
System. out. print ( " ) " ) ;
}
} else if ( node instanceof Numerical ) {
System. out. print ( ( ( Numerical) node) . getValue ( ) ) ;
}
}
}
package calculator;
public interface AvailableValue {
public double getValue ( ) ;
public String getName ( ) ;
}
package calculator;
public abstract class BinaryTree implements AvailableValue {
private BinaryTree father;
private BinaryTree right;
private BinaryTree left;
public BinaryTree findRoot ( BinaryTree node) {
while ( node. getFather ( ) != null ) {
node= node. getFather ( ) ;
}
return node;
}
public BinaryTree findRoot ( ) { return findRoot ( this ) ; }
public void relationshipLeft ( BinaryTree children ) {
this . setLeft ( children) ;
}
public void relationshipRight ( BinaryTree children ) {
this . setRight ( children) ;
}
public BinaryTree getFather ( ) {
return father;
}
public void setFather ( BinaryTree father) {
this . father = father;
}
public BinaryTree getRight ( ) {
return right;
}
public void setRight ( BinaryTree right) {
this . right = right;
}
public BinaryTree getLeft ( ) {
return left;
}
public void setLeft ( BinaryTree left) {
this . left = left;
}
}
运算符需要处理运行时异常
package calculator;
import java. util. ArrayList;
import java. util. HashMap;
import java. util. Map;
public abstract class Operator extends BinaryTree
implements Hierarchical
{
public static Operator createOpertor ( String str) {
if ( funs. containsKey ( str) ) {
return new FunOperator ( str) ;
}
switch ( str) {
case "+" : return new AddOperator ( ) ;
case "-" : return new SubOperator ( ) ;
case "*" : return new MulOperator ( ) ;
case "/" : return new DivOperator ( ) ;
case "^" : return new ExpOperator ( ) ;
case "(" : return new LBraOperator ( ) ;
case ")" : return new RBraOperator ( ) ;
case "," : return new ComOperator ( ) ;
}
return null ;
}
static ArrayList< String> ops= new ArrayList < String> ( ) { {
add ( "+" ) ;
add ( "-" ) ;
add ( "*" ) ;
add ( "/" ) ;
add ( "^" ) ;
add ( "(" ) ;
add ( ")" ) ;
add ( "," ) ;
} } ;
public static Map< String, Function> funs= new HashMap < String, Function> ( ) { {
} } ;
public static void loadFunctionOperator ( Function function ) {
ops. add ( function . getName ( ) ) ;
funs. put ( function . getName ( ) , function ) ;
}
public static boolean isOperator ( String s) { return ops. indexOf ( s) >= 0 ; }
public abstract String getOperator ( ) ;
public abstract int getRank ( ) ;
public abstract double getValue ( ) ;
public String getName ( ) { return "Operator :" + getOperator ( ) ; }
}
class AddOperator extends Operator {
final private int rank= Hierarchical. ADD_SUB ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
return ( ( this . getLeft ( ) == null ) ? 0 : this . getLeft ( ) . getValue ( ) )
+
( ( this . getRight ( ) == null ) ? 0 : this . getRight ( ) . getValue ( ) ) ;
}
public String getOperator ( ) { return " + " ; }
}
class SubOperator extends Operator {
final private int rank= Hierarchical. ADD_SUB ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
return ( ( this . getLeft ( ) == null ) ? 0 : this . getLeft ( ) . getValue ( ) )
-
( ( this . getRight ( ) == null ) ? 0 : this . getRight ( ) . getValue ( ) ) ;
}
public String getOperator ( ) { return " - " ; }
}
class MulOperator extends Operator {
final private int rank= Hierarchical. MUL_DIV ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
return ( ( this . getLeft ( ) == null ) ? 0 : this . getLeft ( ) . getValue ( ) )
*
( ( this . getRight ( ) == null ) ? 0 : this . getRight ( ) . getValue ( ) ) ;
}
public String getOperator ( ) { return " * " ; }
}
class DivOperator extends Operator {
final private int rank= Hierarchical. MUL_DIV ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
if ( this . getRight ( ) != null && this . getRight ( ) . getValue ( ) != 0 ) {
return ( ( this . getLeft ( ) == null ) ? 0 : this . getLeft ( ) . getValue ( ) )
/
this . getRight ( ) . getValue ( ) ;
} System. out. println ( "error X/0 " ) ;
return 0 ;
}
public String getOperator ( ) { return " / " ; }
}
class ExpOperator extends Operator {
final private int rank= Hierarchical. EXP ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
try {
double a= this . getLeft ( ) . getValue ( ) ;
double b= this . getRight ( ) . getValue ( ) ;
return Math. pow ( a, b) ;
} catch ( Exception e) {
System. out. println ( "error " + e) ;
}
return 0 ;
}
public String getOperator ( ) { return " ^ " ; }
}
abstract class BraOperator extends Operator {
final private int rank= Hierarchical. MUL_DIV ;
public int getRank ( ) { return rank; }
public double getValue ( ) {
if ( this . getRight ( ) != null && this . getRight ( ) . getValue ( ) != 0 ) {
return ( ( this . getLeft ( ) == null ) ? 0 : this . getLeft ( ) . getValue ( ) )
/
this . getRight ( ) . getValue ( ) ;
} System. out. println ( "error X/0 " ) ;
return 0 ;
}
public abstract String getOperator ( ) ;
}
class LBraOperator extends BraOperator {
public String getOperator ( ) { return " ( " ; }
}
class RBraOperator extends BraOperator {
public String getOperator ( ) { return " ) " ; }
}
class FunOperator extends Operator {
public ArrayList< BinaryTree> varList= new ArrayList < BinaryTree> ( ) ;
ArrayList< Double> valueList = new ArrayList < Double> ( ) ;
final private int rank= Hierarchical. FUNCTION ;
private String name;
public FunOperator ( String str) { name= str; }
public String getOperator ( ) { return name; }
public int getRank ( ) { return rank; }
public double getValue ( ) {
Operator. funs. get ( name) . setVar ( valueList) ;
return Operator. funs. get ( name) . getValue ( ) ;
}
}
class ComOperator extends Operator {
final private int rank= Hierarchical. COMMA ;
public int getRank ( ) { return rank; }
public double getValue ( ) { return 0 ; }
public String getOperator ( ) { return " , " ; }
}
package calculator;
public class Numerical extends BinaryTree {
private double value= 0 ;
public Numerical ( String string) {
value= Double. valueOf ( string) ;
}
public double getValue ( ) { return value; }
public void setValue ( double value) { this . value= value; }
public String getName ( ) { return "Numerical: " + getValue ( ) ; }
public static boolean isNumerical ( String str) {
String reg = "^[0-9]+(.[0-9]+)?$" ;
return str. matches ( reg) ;
}
}
class Variable extends Numerical {
public String varName;
public Variable ( String string) {
super ( "0" ) ;
varName= string;
}
public String getName ( ) {
return "Variable" + varName;
}
}
package calculator;
import java. util. ArrayList;
import java. util. HashMap;
import java. util. Map;
import java. util. Map. Entry;
public class Function implements AvailableValue {
Map< String, Variable> var = new HashMap < String, Variable> ( ) ;
ArrayList< Variable> varList= new ArrayList < Variable> ( ) ;
ArrayList< String> factor= new ArrayList < String> ( ) ;
BinaryTree root ;
public String name;
public String body;
public static void main ( String[ ] args) {
Map< String, Double> map= new HashMap < String, Double> ( ) ;
map. put ( "a" , 2.0 ) ; map. put ( "b" , 2.0 ) ;
Function f= new Function ( "f(a)=a^2+a*a" ) ;
ArrayList< Double> arr= new ArrayList < Double> ( ) ;
arr. add ( 3. ) ;
f. setVar ( arr) ;
System. out. print ( f. getValue ( ) ) ;
}
public Function ( String str) {
functionSplit ( str) ;
ArrayList< BinaryTree> olist = Objectification ( factor) ;
root = Linker. linkAll ( olist) ;
}
public ArrayList< BinaryTree> Objectification ( ArrayList< String> slist) {
ArrayList< BinaryTree> alist= new ArrayList < BinaryTree> ( ) ;
slist. forEach ( e- > {
if ( Numerical. isNumerical ( e) ) {
alist. add ( new Numerical ( e) ) ;
} else if ( isVariable ( e) ) {
if ( var . get ( e) == null ) {
Variable variable= new Variable ( e) ;
alist. add ( variable) ;
var . put ( e, variable) ;
varList. add ( variable) ;
} else {
alist. add ( var . get ( e) ) ;
}
} else if ( Operator. isOperator ( e) ) {
alist. add ( Operator. createOpertor ( e) ) ;
}
} ) ;
return alist;
}
public String toString ( ) {
String str= "Function Name: " + name+ "\n" ;
str+= "Variable:" ;
for ( Map. Entry< String, Variable> entry : var . entrySet ( ) ) {
str+= " [ " + entry. getKey ( ) + " ] " ;
}
str+= "\n" ;
str+= "Function Body: " + body+ "\n" ;
return str;
}
public void functionSplit ( String str) {
str= str. replace ( " " , "" ) ;
int i= 0 ;
for ( ; i< str. length ( ) ; i++ ) {
if ( str. charAt ( i) == '(' ) {
this . name= str. substring ( 0 , i) ;
break ;
}
}
int last= i+ 1 ;
for ( ; i< str. length ( ) ; i++ ) {
if ( str. charAt ( i) == ')' ) {
if ( i!= last) {
var . put ( str. substring ( last, i) , null ) ;
}
i++ ; break ;
}
if ( str. charAt ( i) == ',' ) {
var . put ( str. substring ( last, i) , null ) ;
last= i+ 1 ;
}
}
if ( str. charAt ( i) == '=' ) {
body= str. substring ( i+ 1 ) ;
factor= division ( body) ;
}
}
public ArrayList< String> division ( String str) {
int last= 0 , now = 0 ;
for ( ; now< str. length ( ) ; ) {
if ( Operator. isOperator ( str. charAt ( now) + "" ) ) {
if ( last== now) {
factor. add ( str. substring ( last, now+ 1 ) ) ;
last++ ;
} else if ( last< now) {
factor. add ( str. substring ( last, now) ) ;
last= now;
factor. add ( str. substring ( last, now+ 1 ) ) ;
last++ ;
}
}
now++ ;
}
if ( last< str. length ( ) ) {
factor. add ( str. substring ( last, str. length ( ) ) ) ;
}
for ( int i= 1 ; i< factor. size ( ) - 1 ; i++ ) {
if ( factor. get ( i) . equals ( "(" ) ) {
if ( ( ! Operator. isOperator ( factor. get ( i- 1 ) )
|| factor. get ( i- 1 ) . equals ( ")" ) ) ) {
factor. add ( i, "*" ) ;
}
} else if ( factor. get ( i) . equals ( ")" ) ) {
if ( ( ! Operator. isOperator ( factor. get ( i+ 1 ) )
|| factor. get ( i+ 1 ) . equals ( "(" ) ) ) {
factor. add ( i+ 1 , "*" ) ;
}
}
}
return factor;
}
public boolean isVariable ( String str) {
return var . containsKey ( str) ;
}
public double setValue ( Map< String, Double> map) {
for ( Entry< String, Double> entry : map. entrySet ( ) ) {
var . get ( entry. getKey ( ) ) . setValue ( entry. getValue ( ) ) ; ;
}
return root. getValue ( ) ;
}
public double setVar ( ArrayList< Double> list) {
for ( int i= 0 ; i< list. size ( ) ; i++ ) {
varList. get ( i) . setValue ( list. get ( i) ) ;
}
return root. getValue ( ) ;
}
public double getValue ( ) {
return root. getValue ( ) ;
}
public String getName ( ) {
return name;
}
public BinaryTree getRoot ( ) {
return root;
}
}
package calculator;
public interface Hierarchical {
final int MIN = 0 ;
final int ADD_SUB = 1 ;
final int MUL_DIV = 2 ;
final int EXP = 3 ;
final int BRACKETS = 4 ;
final int FUNCTION = 5 ;
final int COMMA = 6 ;
final int MAX = 6 ;
int getRank ( ) ;
}
package calculator;
import java. util. ArrayList;
public interface Linker {
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) ;
public static BinaryTree linkAll ( ArrayList< BinaryTree> list) {
Linker r1= new R1Linker ( ) ;
Linker r2= new R2Linker ( ) ;
Linker r3= new R3Linker ( ) ;
Linker r4= new R4Linker ( ) ;
Linker r5= new R5Linker ( ) ;
list= r5. linker ( list) ;
list= r4. linker ( list) ;
list= r3. linker ( list) ;
list= r2. linker ( list) ;
BinaryTree root = r1. linker ( list) . get ( 0 ) ;
return root;
}
}
final class R1Linker implements Linker {
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) {
ArrayList< BinaryTree> rootList= new ArrayList < BinaryTree> ( ) ;
BinaryTree root= null ;
for ( int i= 0 ; i<= list. size ( ) - 1 ; i++ ) {
BinaryTree node = list. get ( i) ;
if ( root== null ) {
rootList. add ( node) ;
root= node;
} else if ( root!= null ) {
if ( root instanceof Numerical ) {
node. relationshipLeft ( root) ;
rootList. remove ( root) ;
root= node;
rootList. add ( root) ;
} else if ( root instanceof Operator ) {
if ( node instanceof Numerical ) {
if ( root. getRight ( ) == null ) {
root. relationshipRight ( node) ;
} else {
rootList. add ( node) ;
root= node;
}
} else if ( node instanceof Operator ) {
if ( root. getRight ( ) == null ) {
root. relationshipRight ( node) ;
} else {
node. relationshipLeft ( root) ;
rootList. remove ( root) ;
root= node;
rootList. add ( root) ;
}
}
}
}
}
return rootList;
}
}
final class R2Linker implements Linker {
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) {
ArrayList< BinaryTree> rootList= new ArrayList < BinaryTree> ( ) ;
BinaryTree root= null ;
for ( int i= 0 ; i<= list. size ( ) - 1 ; i++ ) {
BinaryTree node = list. get ( i) ;
if ( root== null ) {
root= node;
rootList. add ( root) ;
continue ;
}
if ( node instanceof MulOperator
|| node instanceof DivOperator ) {
BinaryTree next = list. get ( i+ 1 ) ;
node. relationshipLeft ( root) ;
node. relationshipRight ( next) ;
rootList. remove ( root) ;
root= node;
rootList. add ( root) ;
i++ ;
} else {
rootList. add ( node) ;
root= node;
}
}
return rootList;
}
}
final class R3Linker implements Linker {
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) {
ArrayList< BinaryTree> rootList= new ArrayList < BinaryTree> ( ) ;
BinaryTree root= null ;
for ( int i= 0 ; i<= list. size ( ) - 1 ; i++ ) {
BinaryTree node = list. get ( i) ;
if ( root== null ) {
root= node;
rootList. add ( root) ;
continue ;
}
if ( node instanceof ExpOperator ) {
BinaryTree next = list. get ( i+ 1 ) ;
node. relationshipLeft ( root) ;
node. relationshipRight ( next) ;
rootList. remove ( root) ;
root= node;
rootList. add ( root) ;
i++ ;
} else {
rootList. add ( node) ;
root= node;
}
}
return rootList;
}
}
final class R4Linker implements Linker {
Linker r1= new R1Linker ( ) ;
Linker r2= new R2Linker ( ) ;
Linker r3= new R3Linker ( ) ;
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) {
int count= 0 ;
ArrayList< BinaryTree> rootList= new ArrayList < BinaryTree> ( ) ;
ArrayList< BinaryTree> braList= new ArrayList < BinaryTree> ( ) ;
BinaryTree node= null ;
BinaryTree root= null ;
for ( int i= 0 ; i< list. size ( ) ; i++ ) {
node = list. get ( i) ;
if ( node instanceof LBraOperator ) {
count-- ;
for ( i= i+ 1 ; i< list. size ( ) ; i++ ) {
node = list. get ( i) ;
if ( node instanceof LBraOperator ) {
count-- ;
} else if ( node instanceof RBraOperator ) {
count++ ;
}
if ( count!= 0 ) {
braList. add ( node) ;
} else
break ;
}
if ( braList. size ( ) > 0 ) {
root= Linker. linkAll ( braList) ;
rootList. add ( root) ;
braList. clear ( ) ;
}
} else {
rootList. add ( node) ;
}
}
return rootList;
}
}
final class R5Linker implements Linker {
public ArrayList< BinaryTree> linker ( ArrayList< BinaryTree> list) {
ArrayList< BinaryTree> rootList= new ArrayList < BinaryTree> ( ) ;
ArrayList< BinaryTree> varList= new ArrayList < BinaryTree> ( ) ;
for ( int i= 0 ; i< list. size ( ) ; i++ ) {
rootList. add ( list. get ( i) ) ;
if ( list. get ( i) instanceof FunOperator ) {
FunOperator fun= ( FunOperator) list. get ( i) ;
i+= 2 ;
int count= 1 ;
int start= i;
for ( ; i< list. size ( ) ; i++ ) {
if ( list. get ( i) instanceof LBraOperator ) {
count++ ;
} else if ( list. get ( i) instanceof RBraOperator ) {
count-- ;
}
if ( ( count== 1 && list. get ( i) instanceof ComOperator ) ||
count== 0 ) {
if ( varList. size ( ) == 0 ) {
continue ;
}
double value= Linker. linkAll ( varList) . getValue ( ) ;
fun. valueList. add ( value) ;
varList. clear ( ) ;
if ( count== 0 ) {
break ;
}
} else {
varList. add ( list. get ( i) ) ;
}
}
}
}
return rootList;
}
}