package Test;
import java.util.Scanner;
//使用栈结构实现综合计算器,
//思路分析
public class TestCalculatorStack {
public static void main(String[] args) {
//有一个被扫描的表达式
Scanner scanner=new Scanner(System.in);
String express=scanner.nextLine();
//创建两个栈,数栈和符号栈
Stack1 numstack=new Stack1(5);
Stack1 operstack=new Stack1(5);
int index =0;//用于扫描
int a=0;
int b=0;
char oper=0;
int res=0;
char ch=' ';//将每次扫描得到的char保存到ch
String keepNumber="";//用于拼接多位数
//开始用while语句循环扫描
while(true){
//依次得到express中的每一个字符
ch=express.substring(index,index+1).charAt(0);//取出字符串中的单个字符
//判断ch是什么,然后做相应的处理
if(operstack.isOper(ch)){//如果是运算符
if(!operstack.isEmpty()){
//符号栈不为空
if(operstack.priority(ch)<=operstack.priority(operstack.peek())){//比较运算符的优先级
//从数栈抛出两个数
a=numstack.pop();
b=numstack.pop();
oper= (char) operstack.pop();
res=numstack.Cal(a,b,oper);
//把res入数栈
numstack.push(res);
//将当前的操作符入符号栈
operstack.push(ch);
}else{
operstack.push(ch);
}
}else{
//符号栈为空,入符号栈
operstack.push(ch);
}
}else{
//如果是数。则直接入数栈
//如果是多位数时,此时应该判断,需要向index后面再看一位,如果是数就继续扫描,如果不是数就入栈
//此时需要定义一个字符串进行拼接
keepNumber+=ch;//先要拼接ch;
//如果ch是最后一位就直接入栈
if(index==express.length()-1){
numstack.push(Integer.parseInt(keepNumber));
}else{
//判断接下来的ch
//如果是符号就入栈。如果是数字就继续扫描,确保能够以多位数进行计算
if(operstack.isOper(express.substring(index+1,index+2).charAt(0))){//查看index后一位到底是符号还是数字
//入栈
numstack.push(Integer.parseInt(keepNumber));
//此时需要清空keepnumber,下一次是新的
keepNumber="";
}
}
}
//让index+1
index++;
if(index>=express.length()){//此时扫描就结束了
break;
}
}
//当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数字和符号
while(true){
if(operstack.isEmpty()){//符号栈为空。则数栈中只有一个数字。此时计算就结束了
break;
}
a=numstack.pop();
b=numstack.pop();
oper= (char) operstack.pop();
res=numstack.Cal(a,b,oper);
//把res入数栈
numstack.push(res);
}
System.out.printf("表达式%s=%d",express,numstack.pop());
}
}
//先创建一个栈
class Stack1{
private int maxsize;
private int stack[];//定义数组模拟栈
private int top=-1;//top表示栈顶,初始化值为-1
//构造器
public Stack1(int maxsize){
this.maxsize=maxsize;
stack=new int[this.maxsize];
}
//增加一个方法,可以返回当前栈顶元素的值。不出栈
public int peek(){
return stack[top];
}
//判断栈满
public boolean isFull(){
return top==maxsize-1;
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int value){
if(isFull()){
System.out.println("栈满不能存放");
return;
}
top++;
stack[top]=value;
}
//出栈
public int pop(){
if(isEmpty()){
//可以抛出一个异常
throw new RuntimeException("栈空,无数据");//此时不需要有return
}
int value=stack[top];
top--;
return value;
}
//显示栈的所有元素
public void showAll(){
if (isEmpty()){
System.out.println("栈空无元素");
return;
}
//遍历时需要从栈顶显示元素
for(int i=top;i>=0;i--){
System.out.printf("stack[%d]=%dn",i,stack[i]);
}
}
//返回运算符的优先级------》优先级由程序员确定-------》优先级用数字表示,数字越大,优先级越高
public int priority(int oper){
if(oper=='*'||oper=='/'){
return 1;
}else if(oper=='+'||oper=='-'){
return 0;
}else {
return -1;
}
}
//判断是不是一个运算符
public boolean isOper(char val){
return val=='+'||val=='-'||val=='*'||val=='/';
}
//计算方法
public int Cal(int a,int b,char oper){
int res=0;//用来存放计算的结果
switch (oper){
case '+':
res=a+b;break;
case '-':
res=b-a;//注意是后面的数字减去前面的数字,出栈顺序
break;
case '*':
res=a*b;break;
case'/':
res=b/a;break;
}
return res;
}
}