公共類函數
{
公共字符串函數;
public int number _ of _ arguments
公共函數(字符串函數,int number_of_arguments)
{
this.function =函數;
this . number _ of _ arguments = number _ of _ arguments;
}
公共字符串toString()
{
返回函數;
}
}
公共類運算符
{
公共字符串運算符;
公共字節優先級;
公共運算符(字符串運算符,字節優先級)
{
this.operator = operator
this.priority =優先級;
}
公共字符串toString()
{
返回運算符;
}
}
公共類變量
{
公共字符串變量;
公共雙值;
公共變量(字符串變量,雙精度值)
{
this.variable =變量;
this.value = value
}
公共字符串toString()
{
返回變量;
}
}
清單2顯示了令牌類。
清單2。令牌類
公共類令牌
{
公共對象令牌;
公共收費標誌;
公共int位置;
public int長度;
公共令牌(對象令牌、字符標記、整數位置、整數長度)
{
this.token = token
this.mark = mark
this.position =位置;
this.length =長度;
}
公共字符串toString()
{
return token . tostring()+";"+標記+";"+位置+";"+長度+"
";
}
}
清單3。三種支架
導入Java . util . stack;
公共類括號_check
{
公共靜態布爾值is _ open _括號(char c)
{
if ( c=='(' || c=='[' || c=='{ ')
返回true
其他
返回false
}
公共靜態布爾值is _ closed _括號(char c)
{
if ( c==')' || c==']' || c=='} ')
返回true
其他
返回false
}
私有靜態布爾括號_match( char open,char closed)
{
if(open = = '(' & amp;& ampclosed== ')')
返回true
else if(open = = '[' & amp;& ampclosed==']')
返回true
else if(open = = ' { ' & amp;& amp閉合=='} ')
返回true
其他
返回false
}
公共靜態布爾括號_valid(字符串表達式)
{
Stack s = new Stack();
int I;
char電流_ char
人物c;
char c 1;
boolean ret = true
for(I = 0;我& ltexp . length();i++)
{
current _ char = exp . charat(I);
if(is _左括號(current_char))
{
c =新字符(current _ char);
s . push(c);
}
else if(is _ closed _括號(current_char))
{
if ( s.isEmpty())
{
ret = false
打破;
}
其他
{
c =(Character)s . pop();
c 1 = c . char value();
如果(!括號_match( c1,current_char))
{
ret = false
打破;
}
}
}
}
如果(!s.isEmpty())
ret = false
返回ret
}
}
清單4。檢查正確表達式的開頭
私有靜態布爾begin_check(向量標記,範圍r,StringBuffer err)
{
字符標記;
token t;
t =(Token)tokens . element at(0);
mark = t.mark
if ( mark=='P ')
err . append(messages . begin _ operator);
else if ( mark== ')')
err . append(messages . begin _括號);
else if ( mark=='Z ')
err . append(messages . begin _ comma);
其他
返回true
r . start = 0;
r . end = t . length;
返回false
}
清單5。找到第壹個右括號
public static int pos _ first _ closed _括號(向量標記)
{
token t;
for(int I = 0;我& lttokens . size();i++)
{
t =(Token)tokens . element at(I);
if ( t.mark== ')')
返回I;
}
返回0;
}
清單6。找到匹配的左括號
public static int pos _ open _括號(向量標記,int closed _括號)
{
int I;
token t;
I =閉_括號-2;
while(I & gt;=0 )
{
t =(Token)tokens . element at(I);
if ( t.mark== '(')
{
返回I;
}
I-;
}
返回0;
}
清單7。找到優先級最高的操作員
public static int pos_operator(向量標記,範圍r)
{
字節最大優先級=字節。MAX _ VALUE
int max _ pos = 0;
字節優先級;
字符串運算符;
token t;
for(int I = r . start+2;我& lt= r . end-2;i++)
{
t =(Token)tokens . element at(I);
如果(t.mark!='P ')
繼續;
優先級=((Operator)t.token)。優先級;
operator=((Operator)t.token)。操作員;
if(優先級& ltmax _ priority | |(operator.equals("^ ")| |
operator . equals(" * *))& amp;& amp優先級==最大優先級)
{
max _ priority =優先級;
max _ pos = I;
}
}
return max _ pos
}
清單8。檢查是否有其他操作員。
...
int poz _ max _ op = pos _ operator(token,range);
//如果沒有運算符
if ( poz_max_op==0)
{
if(無更多括號)
{
返回false
}
其他
{
雙重結果;
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);
括號_移除(tokens,range . start-1);
返回true
}
}
...
清單9。獲取操作數並執行運算...
雙操作數1,操作數2;
//第壹個操作數在前面...
t =(Token)tokens . element at(poz _ max _ op-1);
operand 1 =操作數_值(t);
// ...第二個操作數在運算符之後
t =(Token)tokens . element at(poz _ max _ op+1);
operand2 =操作數_值(t);
//運算符
t =(Token)tokens . element at(poz _ max _ op);
String op=((Operator)t.token)。操作員;
double result = operation _ result(operand 1,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);
括號_移除(tokens,poz _ max _ op-1);
...
清單10。獲取操作數
公共靜態雙操作數_值(標記t)
{
if ( t.mark=='V ')
return((變量)t.token)。價值;
else if ( t.mark=='D ')
return ((Double)t.token)。double value();
else if ( t.mark=='H ')
return base _ convert((String)t . token)。子串(2),16);
else if ( t.mark=='O ')
return base _ convert((String)t . token)。子串(2),8);
else if ( t.mark=='B ')
return base _ convert((String)t . token)。子串(2),2);
}
清單11。將數字轉換成十進制數。
public static long base _ convert(String s,int base)
{
長r = 0;
int i,j;
for ( i=s.length()-1,j = 0;我& gt=0;i -,j++)
r = r+digit _ weight(s . charat(I))*(long)math . pow(base,j);
return r;
}
公共靜態整數數字權重(c字符)
{
if ( Character.isDigit( c))
返回c-48;
else if(' A ' & lt;= c & amp& ampc & lt='f ')
返回c-55;
else if(' a ' & lt;= c & amp& ampc & lt='f ')
返回c-87;
return-1;
}
清單13。移除多余的括號
私有靜態空括號_移除(向量記號,int pos)
{
如果(
pos & gt1。& amp
amp& amp& amp
amp
((Token)tokens.elementAt( poz-2))。馬克。= ' F ' & amp& amp
amp& amp& amp
amp
((Token)tokens . element at(poz-1))。mark = = '(' & amp;& amp
amp& amp& amp
amp
((Token)tokens . element at(poz+1))。mark== ')'
||
pos = = 1 & amp;& amp
amp& amp& amp
amp
((Token)tokens.elementAt( 0))。mark = = '(' & amp;& amp
amp& amp& amp
amp
((Token)tokens.elementAt( 2))。mark== ')'
)
{
tokens . removeelementat(poz+1);
tokens . removeelementat(poz-1);
}
返回;
}
清單14。組合符號並顯示結果
公共靜態字符串token_join(向量令牌)
{
字符串結果=新字符串();
token t;
for(int I = 0;我& lttokens . size();i++)
{
t =(Token)tokens . element at(I);
if ( t.mark=='D ')
{
double n=((Double)t.token)。double value();
結果= result+formated _ number(n);
}
其他
結果=結果+t . token;
if ( result.endsWith( ".0 "))
result=result.substring( 0,result . length()-2);
結果=結果+" ";
}
返回結果;
}
結論
本文分析了壹個applet,它可以逐步計算算術表達式。同時按順序回顧了最感興趣的代碼片段,討論了兩種不同的表達式求值方法。
W3Eval的下壹個版本預計會在各個方面得到增強,包括添加用戶自定義函數的能力;支持分數、復數、矩陣;改進的圖形用戶界面(GUI);尺寸和速度優化以及安全性增強。我鼓勵您提供自己對增強功能的想法。
我希望妳會發現W3Eval是壹個有用的表達式求值的在線工具,它在某種程度上比經典方法更簡單、更自然。我也希望這裏提到的代碼和算法能讓妳明白Java語言是有助於處理數學問題的。
!強烈要求加分!