【数据结构】利用栈来求算术表达式的值

前提是:算术表达式是完全带括号的数字表达式


import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Pattern;


public class CalculateUtils
{
public static final Pattern UNSIGNED_DOUBLE = 
Pattern.compile("((\\d+\\.?\\d*)|(\\.\\d+))([Ee][-+]?\\d+)?.*?");
public static final Pattern CHARACTER = 
Pattern.compile("\\S.*?");
/**
* 对算法表达式求值
* @param expression 一个完全括号化了的算术表达式
* @return 算术表达式的值
*/
public static double evaluate(String expression)
{
// 使用两个栈来分别保存表达式中的数值和运算符
Stack<Double> numbers = new Stack<Double>();
Stack<Character> operations = new Stack<Character>();

// 将表达式转换成一个Scanner类的对象,以便更易于处理
Scanner input = new Scanner(expression);
// next存储的是表达式的下一个片段:数值、运算符或括号
String next;

while (input.hasNext())
{
if (input.hasNext(UNSIGNED_DOUBLE))
{
next = input.findInLine(UNSIGNED_DOUBLE);
numbers.push(new Double(next));
} else {
next = input.findInLine(CHARACTER);
switch (next.charAt(0))
{
case '+':
case '-':
case '*':
case '/':
operations.push(next.charAt(0));
break;
case ')':
evaluateStackTops(numbers, operations);
break;
case '(':
break;
default:
throw new IllegalArgumentException("Illegal input expression.");
}
}
}
if (numbers.size() != 1)
{
throw new IllegalArgumentException("Illegal input expression.");
}
return numbers.pop();
}

/**
* 从数值栈中取出两个数值,并执行一次运算
* @param numbers
* @param operations
*/
public static void evaluateStackTops(Stack<Double> numbers, Stack<Character> operations)
{
double operand1, operand2;
if ((numbers.size() < 2) || (operations.isEmpty()))
{
throw new IllegalArgumentException("Illegal expression.");
}

operand2 = numbers.pop();
operand1 = numbers.pop();

switch (operations.pop())
{
case '+':
numbers.push(operand1 + operand2);
break;
case '-':
numbers.push(operand1 - operand2);
break;
case '*':
numbers.push(operand1 * operand2);
break;
case '/':
numbers.push(operand1 / operand2);
break;
default:
throw new IllegalArgumentException("Illegal operation.");
}
}

public static void main(String[] args)
{
String s1 = "((((12+9)/3)+7.2)*((6-4)/8))";
double value1 = CalculateUtils.evaluate(s1);
System.out.println(value1);

String s2 = "((((6+9)/3)*(6-4))";
double value2 = CalculateUtils.evaluate(s2);
System.out.println(value2);
}
}
计算结果:
3.55
10.0


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章