创建两个栈,一个用来存储数据,一个用来存储符号。
当我们计算表达式的时候一般都是先算乘除然后从左到右进行计算,比如下面的式子。
17 * 2 * 2 +15 -1 + 2 - 3
我们先算17*2
就算变成34,然后在算加之前会用34*2然后其余从左到右计算。
我们用两个栈来模拟,首先将1 7放入数据栈,将 * 放入运算符栈。
接着将2放入数据栈
截下来在存入*之前我们进行比较,如果新存入的运算符的优先级小于等于已经在栈里面的我们就先将栈中的元素取出,从数据栈中取出两个元素进行运算将运算后的数据重新存入栈中。
然后将2存入数据栈。接下来是+,同理进行判断。
最后将运算的68,和接下来的+存入。后面都是都一个道理,如果运算符中有多个运算符,直到要存入的运算符优先于顶部的运算符为止。
代码如下
栈代码
package stack.Arrstack;
public class ArrStack {
private int maxSize;
private int top;
private int[] stack;
public ArrStack(int maxSize) {
top = -1;
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
public int peek(){
return stack[top];
}
public boolean isEmpty() {
return top == -1;
}
public boolean isFull() {
return top == maxSize - 1;
}
public void push(int num) {
if (isFull()){
System.out.println("栈已满");
return;
}
top++;
stack[top]=num;
}
public int pop(){
if (isEmpty()){
throw new RuntimeException("栈为空");
}
int temp = stack[top];
top--;
return temp;
}
public void show(){
if (isEmpty()){
System.out.println("栈为空");
return;
}
for (int i = top ;i>=0;i--){
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
}
运算demo
package stack.Arrstack;
import java.util.Scanner;
public class ComputedExpression {
public static void main(String[] args) {
//定义一个数据栈,一个运算符栈
ArrStack numbers = new ArrStack(10);
ArrStack operator = new ArrStack(10);
//接受表达式
String expression;
Scanner sc = new Scanner(System.in);
System.out.println("请输入表达式");
expression = sc.nextLine();
//将表达式保存在字符数组中
byte[] exp = expression.getBytes();
//用来连接非个位数
String s ="";
//遍历字符数组,将数据压入栈
for (int i = 0; i < exp.length; i++) {
//如果是运算符
if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') {
while (true) {
//判断优先级,优先级高 或者栈为空则直接压入栈
if (operator.isEmpty() || priority(exp[i]) > priority(operator.peek())) {
operator.push(exp[i]);
break;
} else {
//不为空 则计算 在压入栈
int num1 = numbers.pop();
int num2 = 0;
if (!numbers.isEmpty()) {
num2 = numbers.pop();
}
int e = operator.pop();
int res = Compute(num1, num2,e);
numbers.push(res);
}
}
}else{
//如果为数值,进行拼接,因为一次只能取一个字符数组
s= s + (exp[i]-'0');
//判断是否到达末尾
if (i+1<exp.length) {
//如果待压入的数值的后一位不为运算符则拼接,否则直接压入
if (exp[i + 1] == '+' || exp[i + 1] == '-' || exp[i + 1] == '*' || exp[i + 1] == '/') {
numbers.push(Integer.parseInt(s));
s = "";
}
}else{
numbers.push(Integer.parseInt(s));
}
}
}
while (true){
//运算符栈 不为空就计算,为空退出
if (operator.isEmpty()){
break;
}
int e = operator.pop();
int num1 = numbers.pop();
int num2 = 0;
if (!numbers.isEmpty()) {
num2 = numbers.pop();
}
int res = Compute(num1, num2, e);
numbers.push(res);
}
System.out.println("结果是"+numbers.pop());
}
//自定义优先级
public static int priority(int num) {
if (num == '+' || num == '-') {
return 0;
}
if (num == '*' || num == '/') {
return 1;
}
throw new RuntimeException("表达式有误");
}
// 计算
public static int Compute(int num1, int num2, int ope) {
if (ope == '+') {
return num1 + num2;
}
if (ope == '-') {
return num2 - num1 ;
}
if (ope == '*') {
return num1*num2;
}
if (ope == '/') {
return num2 / num1 ;
}
throw new RuntimeException("计算有误");
}
}
纯手写 代码有很大的可能有错误,请大家纠正,谢谢!