栈实现综合计算器
使用栈完成表达式的计算思路
建立两个栈,一个数字栈(numStack)一个符号栈(operStack)
1.通过一个index值(索引),来遍历我们的表达式
2.如果我们扫描到的是一个数字,就直接入栈
3如果我们扫描到的是一个符号,就分如下情况
3.1如果发现当前的符号栈为空,就直接入栈
3.2如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数字,在从符号栈中pop出一个符号,进行运算,将得到的结果入数栈,然后将当前的操作符入符号栈。如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。
4.当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号。
5.最后数栈只有一个数字,就是表达式的结果。
我也根据这个思路,画了个简单的图,如上图
对于以上思路
我们需要在数组模拟栈的基本方法上添加一些别的判断方法
1.priority() *和/的优先级是高于+和-的
2.isOper() 判断是否是运算符,需要将数和运算符存放在两个栈中
3.计算的方式 cal() 对于过程中和结尾 数字栈弹出的两个数和符号栈弹出的符号要进行计算,*和+没有区分,栈先进后出的特性,注意-和/计算时,数字的先后顺序。
重点问题
我认为的
1.在进行四则运算的时候,肯定不可能是都是10以内的运算,我们在将数字入栈的时候是不能直接入栈的,需要判断它的下一位是否是运算符,如果是运算符的话直接入栈,不是的话接着扫描直到符合上述条件。
2.就如我上图所画图的例子 ,但同样的你去分析9+2*3+4,还是有所不同的,在进行数字栈的二次弹栈,和字符栈的弹栈后,不能将优先级小于栈顶的那个运算符直接入栈,是还要进行判断的。
废话不多说代码如下:
package com.zrx.markdown;
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
// 完成表达式的运算
// String exp = "70+20*6-4";
// String exp= "9-2*3+4";
System.out.println("请输入表达式");
Scanner scanner = new Scanner(System.in);
String exp="";
exp=scanner.next();
// 创建两个栈,一个数栈一个符号栈
ArrayStack numStack = new ArrayStack(10);
ArrayStack operStack = new ArrayStack(10);
// 定义需要的相关变量
int index = 0; // 用于扫描
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' '; // 将每次扫描得到的char保存到ch
String keepNum = ""; // 用于拼接多位数
// 开始while循环的扫描exp
while(true) {
// 依次得到exp的每一个字符
ch = exp.charAt(index);
// 判断ch是什么,然后做相应的处理
if(operStack.isOper(ch)) { // 如果是运算符
if(!operStack.isEmpty()) {
if(operStack.priority(ch) <= operStack.priority(operStack.retTop())) {
// num1 = numStack.pop();
// num2 = numStack.pop();
// oper = operStack.pop();
// res = numStack.cal(num1, num2, oper);
// // 把运算的结果入数栈
// numStack.push(res);
// // 把当前的操作符入符号栈
// operStack.push(ch);
while(true){
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
// 把运算的结果入数栈
numStack.push(res);
if(operStack.isEmpty()){
break;
}
if(operStack.priority(ch)> operStack.priority(operStack.retTop())){
break;
}
}
// 把当前的操作符入符号栈
operStack.push(ch);
} else {
// 如果当前的操作符的优先级大于栈中的操作符,直接入符号栈
operStack.push(ch);
}
} else {
// 如果为空直接入符号栈
operStack.push(ch);
}
} else { // 如果是数字,则直接入数栈
keepNum += ch;
if (index == exp.length() - 1) {
numStack.push(Integer.parseInt(keepNum));
} else {
if (operStack.isOper(exp.charAt(index+1))) {
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
// index + 1,并判断是否扫描到最后
index++;
if (index >= exp.length()) {
break;
}
}
// 当表达式扫描完毕时,就顺序的从数栈和符号栈中pop出相应的数和符号并运行
while(true) {
// 如果符号栈为空,则计算到最后的结果,数栈中只有一个数字
if (operStack.isEmpty()) {
break;
} else {
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res); // 入栈
}
}
// 将数栈的最后一个数字pop出就是结果
int result1 = numStack.pop();
System.out.println("result:"+result1);
}
}
class ArrayStack{
private int maxSize;
private int[] stack;
private int top=-1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack=new int[this.maxSize];//初始化数组
}
//判断栈满
public boolean isFull(){
return top==maxSize-1;
}
//判断栈空
public boolean isEmpty(){
return top==-1;
}
//入栈操作
public void push(int value){
//先对栈进行状态判断
if(isFull()){
return;
}
//在进行添加
top++;
stack[top]=value;
}
/**
* 出栈
* 其实就是将栈顶的数据返回
*/
public int pop(){
if (isEmpty()) {
//抛出异常
throw new RuntimeException("stack is empty");
}
int value=stack[top];
top--;
return value;
}
//返回当前栈顶的值
public int retTop(){
return stack[top];
}
//遍历栈,要从栈顶开始遍历
public void list(){
if (isEmpty()) {
throw new RuntimeException("stack is empty");
}
for(int i=top;i>=0;i--){
System.out.println(stack[i]);
}
}
//返回预算符的优先级,直接用数字表示,数字越大优先级越高;
public int priority(int oper){
if(oper=='*' || oper=='/'){
return 1;
}
if(oper=='+' || oper=='-'){
return 0;
}else{
return -1;
}
}
//判断是否是一个运算符
public boolean isOper(char val){
return val=='+' || val=='-' || val=='/' ||val=='*';
}
//计算方法
public int cal(int num1,int num2,int val){
int res=0;//存放计算的结果;
switch (val){
case '+':
res=num1+num2;
break;
case '-':
res=num2-num1;
break;
case '*':
res=num1*num2;
break;
case '/':
res=num2/num1;
break;
default:
break;
}
return res;
}
}
是谁写代码不加注释,嗷,是我那没事儿了
哈哈哈哈嗝 溜了 溜了