思想:
为实现运算符优先算法,可以使用两个栈。一个是OPTR,存放运算符;一个是OPND,存放运算结果。
1.首先置OPND为空栈,表达式起始符“#”为栈底元素;
2.依次读入表达式中每个元素,若是操作数则进OPND,若是运算符则和OPTR栈中的栈顶运算符比较优先权后作相应操作,直至整个表达式求值完毕。(栈顶运算符优先权低,push操作, 栈顶运算符优先级高,取出两个数运算,再把结果push进去,最后留在OPND中的就是运算结果)
完整代码:
package com.stack;
import java.util.Stack;
/**
* 中缀表达式求值
*
* @author Administrator
*/
public class EvaluateExpression {
public static void main(String[] args) {
String exp = "1.5 + 22 * ( 4 + 1 ) / 2 #";//元素间以空格隔开
float result = evaluateExpression(exp);
System.out.println("result-:" + result);
}
/**
* 表达式求值
*/
public static float evaluateExpression(String exp) {
Stack
Stack
OPTR.push("#");
String theta;
int i = 0;
float b, c;
String[] exps = exp.split(" ");// 表达式
while (true) {
if (ReadNum(exps[i]) != 0) {
OPND.push(ReadNum(exps[i++]));
} else if (exps[i].equals("+") || exps[i].equals("-")
|| exps[i].equals("*") || exps[i].equals("/")
|| exps[i].equals("#") || exps[i].equals("(")
|| exps[i].equals(")")) {
switch (Precede(exps[i], OPTR.lastElement())) {
case "<":
OPTR.push(exps[i++]);
break;
case "=":
OPTR.pop();
i++;
break;
case ">":
theta = OPTR.pop();
c = OPND.pop();
b = OPND.pop();
OPND.push(Operate(b, theta, c));
break;
}// switch
}// else if
if (exps[i].equals("#") && OPTR.lastElement().equals("#")) {
System.out.println("结果是 --:" + OPND.lastElement()); // 打印输出表达式值
return OPND.lastElement();
}
}// while
}
/**
* 转化成float数
*
* @param s
* @return
*/
public static float ReadNum(String s) // 将字符型的数字转化成Float型
{
try {
return Float.valueOf(s);
} catch (Exception e) {
return 0f;
}
}// ReadNum
/**
* 运算符优先级判定
*
* @param a
* @param b
* @return
*/
public static String Precede(String a, String b) {
int i, j;
String[][] Table = { { " ", "+", "-", "*", "/", "(", ")", "#" },
{ "+", ">", ">", "<", "<", "<", ">", ">" },
{ "-", ">", ">", "<", "<", "<", ">", ">" },
{ "*", ">", ">", ">", ">", "<", ">", ">" },
{ "/", ">", ">", ">", ">", "<", ">", ">" },
{ "(", "<", "<", "<", "<", "<", "=", " " },
{ ")", ">", ">", ">", ">", " ", ">", ">" },
{ "#", "<", "<", "<", "<", "<", " ", "=" } };
for (i = 0; i < 8; i++)
if (Table[0][i].equals(a)) // 纵坐标寻找
break;
for (j = 0; j < 8; j++)
// 横坐标寻找
if (Table[j][0].equals(b))
break;
return Table[j][i];
}// Precede
/**
* 运算
*
* @param a
* @param theta
* @param b
* @return
*/
public static float Operate(float a, String theta, float b) // 计算表达式值:主要是将大的表达式
{ // 转化成小的表达式进行逐步求值
float c;
if (theta.equals("+"))
c = a + b;
else if (theta.equals("-"))
c = a - b;
else if (theta.equals("*"))
c = a * b;
else
c = a / b;
return c;
}// Operate
}