一、问题分析
【问题描述】
设计一个简单的算术表达式计算器。
【基本要求】
实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入).
【测试数据】
(30+2*70)/3-12*3
5+(9*(62-37)+15)*6
要求自行设计非法表达式,进行程序测试,以保证程序的稳定运行。
【实现提示】
可以设计以下辅助函数
status isNumber(char ReadInChar); //视ReadInchar 是否是数字而返回 TRUE 或 FALSE
int TurnToInteger(char IntChar); // 将字符’0’.’9’ 转换为整数 9
二、类定义
calculate类:用于转换和计算后缀表达式
simplify类:用于解决负数的问题,例如-9=>(0-9)
isOpe类:用于判断是否为正确的运算符
isAllOpe类:用于判断是否为正确的运算符或者括号
isGreater类:用于判断字符两个字符的等级
getLevel类:用于获取一个字符的优先级
isNumeric类:用于判断是否为数字
三、设计
1、判断输入是否为有效字符(数字和运算符和括号)
2、判断优先级
3、将输入的表达式转换为后缀表达式
4、计算后缀表达式
四、部分代码
public static int calculate(String strExpression)
{
String s = simplify(strExpression);
System.out.println("s : "+s);
String numStr = "";//记录数字
Stack<Character> opeStack = new Stack<>();//符号栈
int l = s.length();//字符串长度 l
List<String> list = new ArrayList<>();
for(int i=0;i<l;i++)
{
char ch = s.charAt(i);
if(isAllOpe(ch))
{
if(numStr!="")
{
list.add(numStr);
numStr="";
}
if(ch=='(')
{
opeStack.push(ch);
}
else if(isOpe(ch))
{
char top = opeStack.peek();
if(isGreater(ch, top))
// ch优先级大于top 压栈
{
opeStack.push(ch);
}
else
//否则,将栈内元素出栈,直到遇见 '(' 然后将ch压栈
{
while(true)
//必须先判断一下 后出栈 否则会有空栈异常
{
char t=opeStack.peek();
if(t=='(')
break;
if(isGreater(ch, t))
break;
list.add(Character.toString(t));
t=opeStack.pop();
}
opeStack.push(ch);
}
}
else if(ch==')')
{
char t = opeStack.pop();
while(t!='('&&!opeStack.isEmpty())
{
list.add(Character.toString(t));
t = opeStack.pop();
}
}
}
else//处理数字
{
numStr+=ch;
}
}
//计算后缀表达式
System.out.println(list.toString());
Stack<Double> num = new Stack<>();
int size = list.size();
for(int i=0;i<size;i++)
{
String t =list.get(i);
if(isNumeric(t))
{//将t转换成double 方便计算
num.push(Double.parseDouble(t));
}
else
{
//如果t为运算符则只有一位
char c = t.charAt(0);
double b = num.pop();
//如果有 算式是类似于 -8-8 这样的需要判断一下栈是否为空
double a = num.pop();
switch(c)
{
case '+':
num.push(a+b);
break;
case '-':
num.push(a-b);
break;
case '*':
num.push(a*b);
break;
case '/':
num.push(a/b);
break;
default:
break;
}
}
}
System.out.println(num.pop());
return 0;
}