原理
* 四则优先计算器思路: @0xdF
* 对符号栈进行出栈操作,如果出栈的符号为低优先级的+、-,则使用peek方法获取符号栈下一个符号,
* 如果下一个符号为优先级高的 *、/ 则从数字栈取出三个数字,将后面两个数字通过高优先的计算后再入栈,最后再将当前低优先级的符号入栈即可。
代码
import java.util.Stack;
/***
* 四则优先计算器思路: @0xdF
* 对符号栈进行出栈操作,如果出栈的符号为低优先级的+、-,则使用peek方法获取符号栈下一个符号,
* 如果下一个符号为优先级高的 *、/ 则从数字栈取出三个数字,将后面两个数字通过高优先的计算后再入栈,最后再将当前低优先级的符号入栈即可。
*/
public class calc {
public static void main(String[] args) {
Stack<String> stkNum = new Stack<>();
Stack<String> stkOp = new Stack<>();
String compute = "3*4+4/2-2*2+12/2+2";
saveStack(compute,stkNum,stkOp);
printStack(stkNum,stkOp);
compute(stkNum,stkOp);
}
private static void printStack(Stack<String>... stacks){
for(Stack<String> stack:stacks){
for(String s:stack){
System.out.print(s+",");
}
}
System.out.println();
}
//将输入的结果入栈
private static void saveStack(String compute,Stack<String> stkNum,Stack<String> stkOp){
String num = "";
for(int i =0;i<=compute.length()-1;i++){
switch (compute.charAt(i)){
case '+':
stkNum.push(num);
stkOp.push("+");
num = "";
break;
case '-':
stkNum.push(num);
stkOp.push("-");
num = "";
break;
case '*':
stkNum.push(num);
stkOp.push("*");
num = "";
break;
case '/':
stkNum.push(num);
stkOp.push("/");
num = "";
break;
default:
num+=compute.charAt(i);
break;
}
}
stkNum.push(num); //最后一个数字组合后没有被提交
}
private static void compute(Stack<String> stkNum,Stack<String> stkOp){
String res ="0",scRes="1",flag="0";
if(stkNum.size()==stkOp.size()+1){
Integer num0,num1,num2;
String nextOP = "";
//开始计算
while (!stkOp.isEmpty()){
String op = stkOp.pop();
switch (op){
case "+":
if(!stkOp.isEmpty()){
nextOP = stkOp.peek();
if(nextOP.equals("/")||nextOP.equals("*")){
stkOp.pop(); //将本次计算的符号出栈
stkOp.push("+"); //加号暂时不计算,重新入栈
//表示下个符号为优先的符号
num0 = Integer.valueOf(stkNum.pop()); //这是被加数,后面要放回栈里
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
if(nextOP.equals("*")){
stkNum.push(String.valueOf(num1*num2));
}else {
stkNum.push(String.valueOf(num2/num1));
}
stkNum.push(String.valueOf(num0));
}else{
if(nextOP.equals("-")){
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num2-num1)); //将本次相加的结果入栈
}else{
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num1+num2)); //将本次相加的结果入栈
}
}
}else{
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num1+num2)); //将本次相加的结果入栈
}
break;
case "-":
if(!stkOp.isEmpty()){
nextOP = stkOp.peek();
if(nextOP.equals("/")||nextOP.equals("*")){
stkOp.pop(); //将本次计算的符号出栈
stkOp.push("-"); //加号暂时不计算,重新入栈
//表示下个符号为优先的符号
num0 = Integer.valueOf(stkNum.pop()); //这是被减数,后面要放回栈里
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
if(nextOP.equals("*")){
stkNum.push(String.valueOf(num1*num2));
}else {
stkNum.push(String.valueOf(num2/num1));
}
stkNum.push(String.valueOf(num0));
}else{
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num2-num1)); //将本次相减的结果入栈
}
}else{
if(nextOP.equals("-")){
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num2-num1)); //将本次相加的结果入栈
}else{
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
stkNum.push(String.valueOf(num1+num2)); //将本次相加的结果入栈
}
}
break;
case "*":
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
scRes = String.valueOf((num1*num2));
stkNum.push(scRes);
break;
case "/":
num1 = Integer.valueOf(stkNum.pop());
num2 = Integer.valueOf(stkNum.pop());
scRes = String.valueOf((num2/num1));
stkNum.push(scRes);
break;
}
}
System.out.println(stkNum.pop());
}else {
System.out.println("数据校验错误!");
}
}
}