JAVA计算数学表达式的程序

Python010

JAVA计算数学表达式的程序,第1张

清单 1. Function、Operator 和 Variable 类的定义

public class Function

{

public String function

public int number_of_arguments

public Function( String function, int number_of_arguments )

{

this.function=function

this.number_of_arguments=number_of_arguments

}

public String toString()

{

return function

}

}

public class Operator

{

public String operator

public byte priority

public Operator( String operator, byte priority )

{

this.operator=operator

this.priority=priority

}

public String toString()

{

return operator

}

}

public class Variable

{

public String variable

public double value

public Variable( String variable, double value )

{

this.variable=variable

this.value=value

}

public String toString()

{

return variable

}

}

Token 类如清单 2 所示。

清单 2. Token 类

public class Token

{

public Object token

public char mark

public int position

public int length

public Token ( Object token, char mark, int position, int length )

{

this.token=token

this.mark=mark

this.position=position

this.length=length

}

public String toString()

{

return token.toString()+" "+mark+" "+position+" "+length+"

"

}

}

清单 3. 三种括号

import java.util.Stack

public class Parentheses_check

{

public static boolean is_open_parenthesis( char c )

{

if ( c=='(' || c=='[' || c=='{' )

return true

else

return false

}

public static boolean is_closed_parenthesis( char c )

{

if ( c==')' || c==']' || c=='}' )

return true

else

return false

}

private static boolean parentheses_match( char open, char closed )

{

if ( open=='(' &&closed==')' )

return true

else if ( open=='[' &&closed==']' )

return true

else if ( open=='{' &&closed=='}' )

return true

else

return false

}

public static boolean parentheses_valid( String exp )

{

Stack s = new Stack()

int i

charcurrent_char

Character c

charc1

boolean ret=true

for ( i=0i <exp.length()i++ )

{

current_char=exp.charAt( i )

if ( is_open_parenthesis( current_char ) )

{

c=new Character( current_char )

s.push( c )

}

else if ( is_closed_parenthesis( current_char ) )

{

if ( s.isEmpty() )

{

ret=false

break

}

else

{

c=(Character)s.pop()

c1=c.charValue()

if ( !parentheses_match( c1, current_char ) )

{

ret=false

break

}

}

}

}

if ( !s.isEmpty() )

ret=false

return ret

}

}

清单 4. 正确的表达式开头的检查

private static boolean begin_check( Vector tokens, Range r, StringBuffer err )

{

char mark

Tokent

t=(Token)tokens.elementAt( 0 )

mark=t.mark

if ( mark=='P' )

err.append( Messages.begin_operator )

else if ( mark==')' )

err.append( Messages.begin_parenthesis )

else if ( mark=='Z' )

err.append ( Messages.begin_comma )

else

return true

r.start=0

r.end=t.length

return false

}

清单 5. 找出第一个闭括号

public static int pos_first_closed_parenthesis( Vector tokens )

{

Token t

for ( int i=0i<tokens.size()i++ )

{

t=(Token)tokens.elementAt( i )

if ( t.mark==')' )

return i

}

return 0

}

清单 6. 找出匹配的开括号

public static int pos_open_parenthesis( Vector tokens, int closed_parenthesis )

{

int i

Tokent

i=closed_parenthesis-2

while ( i>=0 )

{

t=(Token)tokens.elementAt( i )

if ( t.mark=='(' )

{

return i

}

i--

}

return 0

}

清单 7. 找出优先级最高的操作符

public static int pos_operator( Vector tokens, Range r )

{

byte max_priority=Byte.MAX_VALUE

int max_pos=0

byte priority

String operator

Tokent

for ( int i=r.start+2i<=r.end-2i++ )

{

t=(Token)tokens.elementAt( i )

if ( t.mark!='P' )

continue

priority=((Operator)t.token).priority

operator=((Operator)t.token).operator

if ( priority <max_priority || ( operator.equals("^") ||

operator.equals("**") ) &&priority == max_priority )

{

max_priority=priority

max_pos=i

}

}

return max_pos

}

清单 8. 检查是否还有其它操作符

...

int poz_max_op=pos_operator( tokens, range )

// if there are no operators

if ( poz_max_op==0 )

{

if ( no_more_parentheses )

{

return false

}

else

{

double result

result=function_result( tokens, range.start-1 )

function_tokens_removal( tokens, range.start-1 )

t = new Token ( new Double(result), 'D', 0, 0 )

tokens.setElementAt( t, range.start-1 )

parentheses_removal( tokens, range.start-1 )

return true

}

}

...

清单 9. 获取操作数并执行运算...

double operand1, operand2

// first operand is before...

t=(Token)tokens.elementAt( poz_max_op-1 )

operand1=operand_value( t )

// ...and second operand is after operator

t=(Token)tokens.elementAt( poz_max_op+1 )

operand2=operand_value( t )

// operator

t=(Token)tokens.elementAt( poz_max_op )

String op=((Operator)t.token).operator

double result=operation_result( operand1, operand2, op )

tokens.removeElementAt( poz_max_op+1 )

tokens.removeElementAt( poz_max_op )

t = new Token ( new Double(result), 'D', 0, 0 )

tokens.setElementAt( t, poz_max_op-1 )

parentheses_removal( tokens, poz_max_op-1 )

...

清单 10. 获取操作数

public static double operand_value( Token t )

{

if ( t.mark=='V' )

return ((Variable)t.token).value

else if ( t.mark=='D' )

return ((Double)t.token).doubleValue()

else if ( t.mark=='H' )

return base_convert( ((String)t.token).substring(2), 16 )

else if ( t.mark=='O' )

return base_convert( ((String)t.token).substring(2), 8 )

else if ( t.mark=='B' )

return base_convert( ((String)t.token).substring(2), 2 )

}

清单 11. 将数转化为十进制数

public static long base_convert( String s, int base )

{

long r=0

int i, j

for ( i=s.length()-1, j=0i>=0i--, j++ )

r=r+digit_weight( s.charAt( i ) )*(long)Math.pow( base, j )

return r

}

public static int digit_weight( char c )

{

if ( Character.isDigit( c ) )

return c-48

else if ( 'A'<=c &&c<='f' )

return c-55

else if ( 'a'<=c &&c<='f' )

return c-87

return -1

}

清单 13. 除去冗余括号

private static void parentheses_removal( Vector tokens, int pos )

{

if (

pos>1 &&

amp&&

amp

((Token)tokens.elementAt( poz-2 )).mark!='F' &&

amp&&

amp

((Token)tokens.elementAt( poz-1 )).mark=='(' &&

amp&&

amp

((Token)tokens.elementAt( poz+1 )).mark==')'

||

pos==1 &&

amp&&

amp

((Token)tokens.elementAt( 0 )).mark=='(' &&

amp&&

amp

((Token)tokens.elementAt( 2 )).mark==')'

)

{

tokens.removeElementAt( poz+1 )

tokens.removeElementAt( poz-1 )

}

return

}

清单 14. 结合符号并显示结果

public static String token_join( Vector tokens )

{

String result=new String()

Tokent

for ( int i=0i <tokens.size()i++ )

{

t=(Token)tokens.elementAt( i )

if ( t.mark=='D' )

{

double n=((Double)t.token).doubleValue()

result=result + formated_number( n )

}

else

result=result + t.token

if ( result.endsWith( ".0" ) )

result=result.substring( 0, result.length()-2 )

result=result + " "

}

return result

}

结论

本文分析了一个 applet ,它能一步一步的对算术表达式求值。同时还按顺序回顾了最有意思的代码片段,并论述了两种不同的表达式求值方法。

下一版 W3Eval 有望在各方面得到增强,包括有能力添加用户定义的功能;支持分数、复数和矩阵;改良的图形用户界面(GUI);大小和速度优化以及安全性方面的增强。我鼓励您提供您自己对于增强方面的设想。

我希望您会发现 W3Eval 是个对表达式求值有益的在线工具,它在某种程度上比经典的方法更简单自然。我还期待这里谈到的代码和算法使您明白 Java 语言有助于处理数学问题。

!强烈要求加分!

System.out.println("\t" + n + "! = " + compute(n))//调用compute方法,传入参数n

}

// 计算n!的方法

static long compute(int n) {

// 1!=1 2!=2*1=2 3!=3*2*1 4!=4*3! ... n!=n*(n-1)!

// 递归: 方法本身含有对自己的调用

if (n == 1) {

return 1

} else {

return n*compute(n-1)//20*compute(20-1)

}

}

lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。

函数式接口:

这个是理解Lambda表达式的重点,也是产生lambda表达式的“母体”,这里我们引用一个比较容易理解的说法:函数式接口是 一个只有一个抽象方法(不包含object中的方法)的接口。

这个需要说明一点,就是在Java中任何一个对象都来自Object 所有接口中自然会继承自Object中的方法,但在判断是否是函数式接口的时候要排除Object中的方法。