计算一个算数表达式(包括四则运算)
比如 3 + 4 * 2-5
1.需要遍历字符串,获取每一个字符
2.判断当前字符是一个运算符还是一个数字
3.把数字存放在数字栈中,把运算符放在运算符栈
4.运算符栈: 如果是一个空栈,那么直接运算符入栈,如果运算符栈中已经了其他运算符 就需要先对比运算符优先级,新进来的运算符如果小于等于原栈中运算符,那么需要把原运 算符弹栈 ,数字栈中数字进行弹栈,进行运算,运算后的结果重新放入数字栈中,新运算符入栈。 如果新运算符优先级大于原符号栈中运算符,那么新的符号直接入栈
这是我们用到的栈,用数组来实现
public class ArrayStack {
//定义栈的大小为10,top=-1代表栈目前没有元素
private int maxStack;
private int top = -1;
//用数组来模拟栈
private int[] stack;
/**
* 初始化栈
* @param maxStack 栈的大小
*/
public ArrayStack(int maxStack) {
this.maxStack = maxStack;
//这一步是关键,this.stack而不是stack
this.stack = new int[this.maxStack];
}
/**
* 入栈
*/
public void push(int value){
if (isFull()) {
throw new RuntimeException("栈已满");
}
top++;
stack[top] = value;
}
/**
* 出栈
*/
public int pop(){
if (isEmpty()) {
throw new NullPointerException("栈已空");
}
int value = stack[top];
top--;
return value;
}
/**
* 判断是否为空
* @return
*/
public boolean isEmpty(){
return this.top == -1;
}
/**
* 判断是否满栈
* @return
*/
public boolean isFull(){
return this.top == maxStack-1;
}
/**
* 查看栈中数据
*/
public void list(){
if (isEmpty()){
throw new NullPointerException("空栈");
}
for (int i = 0; i < top+1; i++) {
System.out.println(stack[i]);
}
}
/**
* 输出数组元素个数
*/
public int length(){
return this.top+1;
}
/**
* 判断是否是运算符
*/
public boolean isOper(char v){
return v=='+' || v=='-' || v=='*' || v=='/';
}
/**
* 获取栈顶的元素
*/
public int getTop(){
return this.stack[top];
}
/**
* 获取栈的容量
*/
public int stackLength(){
return this.stack.length;
}
/**
* 计算两个数进行运算后的结果
* 2-3
* 3:num1 2:num2
*/
public int calculate(int num1,int num2,int oper){
//计算结果
int result = 0;
switch (oper){
case '+':
result = num1+num2;
break;
case '-':
result = num2-num1;
break;
case '*':
result = num1*num2;
break;
case '/':
result = num2/num1;
break;
default:
break;
}
return result;
}
/**
* 比较运算符优先级 返回数字越大代表优先级越大
*/
public int priority(int oper){
if (oper=='*' || oper=='/') {
return 1;
}else if (oper=='+' || oper=='-'){
return 0;
}else{
return -1;
}
}
}
写一个测试来看看
public static void main(String[] args) {
String str = "44+3*2-12/2";
int length = str.length();
/**
* 1.需要遍历字符串,获取每一个字符
* 2.判断当前字符是一个运算符还是一个数字
* 3.把数字存放在数字栈中,把运算符放在运算符栈
* 4.运算符栈: 如果是一个空栈,那么直接运算符入栈,如果运算符栈中已经了其他运算符
* 就需要先对比运算符优先级,新进来的运算符如果小于等于原栈中运算符,那么需要把原运算符弹栈
* ,数字栈中数字进行弹栈,进行运算,运算后的结果重新放入数字栈中,新运算符入栈。
* 如果新运算符优先级大于原符号栈中运算符,那么新的符号直接入栈
*/
ArrayStack numStack = new ArrayStack(10);
ArrayStack symbolStack = new ArrayStack(10);
/**
* 获取字符串长度
*/
for (int i=0;i<length;i++){
//取出来
char c = str.charAt(i);
/**
* 是否是一个运算符
*/
if (symbolStack.isOper(c)){
/**
* 如果不是一个空符号栈
*/
if (!symbolStack.isEmpty()){
//比较运算符的优先级
if (symbolStack.priority(c) < symbolStack.priority(symbolStack.getTop())){
/**
* 1.去符号栈中获取栈顶的符号
* 2.去数字栈中获取两个数字
*/
int temp1 = numStack.pop();
int temp2 = numStack.pop();
int symbolChar = symbolStack.pop();
int result = numStack.calculate(temp1,temp2,symbolChar);
//把运算结果再次放入数字栈中
numStack.push(result);
//把当前符号压入符号栈中
symbolStack.push(c);
}else {
symbolStack.push(c);
}
}else {
//如果是空符号栈,讲运算符直接压栈
symbolStack.push(c);
}
}else {
// 如果不是符号栈,则是数字栈,但是我们第一个数字是44
String values+=c;
//如果是最后一个数字,则直接入栈
if (i==length-1){
numStack.push(Integer.parseInt(values));
}else {
char data = str.substring(i+1,i+2).charAt(0);
if (symbolStack.isOper(data)){
numStack.push(Integer.parseInt(values));
values="";
}
}
}
}
/**
* 上面其实相当于把乘除先给解决了,这里都是些加减
*/
while (true){
if (symbolStack.isEmpty()){
break;
}
int temp1 = numStack.pop();
int temp2 = numStack.pop();
int symbolChar = symbolStack.pop();
int result = numStack.calculate(temp1,temp2,symbolChar);
numStack.push(result);
}
int res = numStack.pop();
System.out.println("结果是: "+res);
}
当成一个练习试试吧,试着看懂自己敲一个,你会发现你可能哪就报错了,哈哈