问题提出:
实现普通数学式子运算,如"7*2*2-5+1-5+3-4";
实现思路:
1、首先定义两个栈,一个是数据栈,一个是符号栈
2、依次输入字符串的每个字符,如果是一个数字,直接入栈,如果是字符,分情况,判断当前的运算符的优先级与栈顶元素的优先级的大小,如果栈中的优先级大一点那么需要将其与数字栈中的两个栈顶元素进行运算。
3、如果是空栈,那么字符串直接入栈,如果是非空串,就需要判断字符已经入栈的字符串与即将入栈的字符串的大小
代码实现:
public class CalvulatorCommon {
public static void main(String[] args) {
String expression = "7*2*2-5+1-5+3-4";
//使用sqlpt方法对字符串进行分割
String[] split = expression.split("");
int index = 0;//扫描标记
String num1 = ""; //操作数1
String num2 = ""; //操作数2
String oper = ""; //运算符
int result = 0; //运算结果
Stack<String> numStack = new Stack<>();
Stack<String> operStack = new Stack<>();
String s = " ";
while (true){
s= split[index];
if (isOper(s)){
//如果是操作符需要进行讨论
//如果字符栈为空,那么直接入栈,否则就需要进行比
if(!operStack.isEmpty()){
//peek()函数返回栈顶的元素,但不弹出该栈顶元素。
//pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
if (priority(s)<=priority(operStack.peek())){
num1=numStack.pop();
num2=numStack.pop();
oper=operStack.pop();
result= operCacul(num1,num2,oper);
numStack.push(result+"");
operStack.push(s);
}else{
operStack.push(s);
}
} else{
operStack.push(s);
}
}else{
//如果是数字,直接入栈
numStack.push(s);
}
index++;
if (index>=expression.length()){
break;
}
}
//当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运行.
while(true) {
//如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字
if(operStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
result = operCacul(num1,num2,oper);
numStack.push(result+"");//入栈
}
//将数栈的最后数,pop出,就是结果
String res2 = numStack.pop();
System.out.println(res2);
// System.out.printf("表达式 %s = %d", expression, res2);
}
//实现计算的方法
public static int operCacul(String num1, String num2, String oper) {
int i = Integer.parseInt(num1);
int j=Integer.parseInt(num2);
int res = 0;
switch (oper) {
case "+":
res = i + j;
break;
case "-":
res = j - i;
break;
case "*":
res = i * j;
break;
case "/":
res = j / i;
break;
}
return res;
}
public static boolean isOper(String val) {
return val.equals("+") || val.equals("-") || val.equals("*") || val.equals("/");
}
//返回运算符的优先级,优先级是程序员来确定, 优先级使用数字表示
//数字越大,则优先级就越高.
public static int priority(String oper) {
if (oper.equals("*") || oper.equals("/")) {
return 1;
} else if (oper.equals("+") || oper.equals("-")) {
return 0;
} else {
return -1; // 假定目前的表达式只有 +, - , * , /
}
}
}