package day7;
import java.util.Scanner;
public class jisuanqi {
public static void main(String[] args) {
System.out.println("请输入一个表达式");
String next = new Scanner(System.in).next();
String expression =next;
// 创建两个栈
arrarystack2 numberstack = new arrarystack2(10);
arrarystack2 operstack = new arrarystack2(10);
int index=0; //用于扫描
int a=0;
int b=0;
int res=0;
char ch; //当前操作符
int oper; //栈中的操作符
String keepnumber ="";
while (true){
// 依次取出每个字符 substring(起始位置,结束位置) charat(0)是把第一个字符取出来
ch =expression.substring(index,index+1).charAt(0);
if (operstack.isoper(ch)){ //如果是运算符
if (operstack.isempty()){ //判断是否为空
// 入栈
operstack.push(ch);
}else {
// 入符号栈中判断符号的优先级,如果要入栈的符号的优先级小于等于栈中的符号,则弹出2个数字栈和栈中的符号,进行运算,
if (operstack.priority(ch)<= operstack.priority(operstack.pick())){
a=numberstack.pop();
b=numberstack.pop();
oper =operstack.pop();
res =numberstack.cal(a,b,oper);
numberstack.push(res);
operstack.push(ch);
} else { //当前优先级大于
operstack.push(ch);
}
}
}else { //如果是数字
// numberstack.push(ch-48); //因为存放的为char ascll码差48
// ------------------------------------------------改进--------------------------------
// 思路:如果是数字不能直接如数字栈,多位数会出现错误。
// 要判断数字的后一位,如果是数就拼接,如果是符号就入栈
// 因此我们需要定义一个字符串遍历用于拼接。
keepnumber += ch;
if (index==expression.length()-1){
numberstack.push(ch);
}else {
//判断下一个是不是数字,如果是数字,就继续扫描,如果是运算符就入栈
if (operstack.isoper(expression.substring(index+1,index+2).charAt(0))){
// 查看下一位 index+1
numberstack.push(Integer.parseInt(keepnumber)-48);
// 清空keepnumber
keepnumber ="";
}
}
}
index++;
if (index >=expression.length()){ //扫描结束 跳出循环
break;
}
}
while (true){ //如果符号栈为空,数字栈中只有一个数就是结果
if (operstack.isempty()){
break;
}
a=numberstack.pop();
b=numberstack.pop();
oper =operstack.pop();
res =numberstack.cal(a,b,oper);
numberstack.push(res);
}
//将数字栈的数字pop出来
System.out.printf("%s=%d",expression,numberstack.pop());
}
}
class arrarystack2{
private int maxsize;
int top=-1;
int[] stack1; //存放栈的数组
public arrarystack2(int maxsize) { //构造函数
this.maxsize = maxsize;
stack1 = new int[maxsize];
}
// 判断栈空
public boolean isempty(){
return top==-1;
}
// 判断为满
public boolean isfull(){
return top+1==maxsize;
}
// 出栈
public int pop(){
if (isempty()){
throw new RuntimeException("为空");
}
// 出栈就是将栈顶的元素
int temp =stack1[top];
top--;
return temp;
// return语句要在最后 所以要一个零时变量来存储栈的值
}
// 入栈
public void push(int value){
if (isfull()){
System.out.println("栈满");
return;
}
top++;
stack1[top]=value;
}
// 遍历
public void list(){
if (isempty()){
System.out.println("为空,没有数据");
}
for (int i=top;i>=0;i--){
System.out.printf("stack1[%d]=%d",i,stack1[i]);
System.out.println();
}
}
// 返回当前栈顶的值
public int pick(){
return stack1[top];
}
// 判断优先级
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,int 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;
}
}
//思路:完成计算器功能
//1. 需要一个变量来遍历计算表达式。
//2.如果字符为数字就入数字栈,为表达式就如表达式栈。
//3.计算过程判断 (1)如果入站过程中符号栈为空,就直接入,
// (2)入符号栈中判断符号的优先级,如果要入栈的符号的优先级小于等于栈中的符号,则弹出2个数字栈和栈中的符号,进行运算,
//将得到的结果压入数字栈,并将字符压入符号栈。
//(3)如果优先级大于栈中的,则直接压入栈中。
//最后只剩下数字栈的最后一个数字。
计算器的加减乘除(中缀)
于 2022-08-11 14:34:21 首次发布