|
@@ -0,0 +1,221 @@
|
|
|
+package com.example;
|
|
|
+
|
|
|
+import java.util.EmptyStackException;
|
|
|
+
|
|
|
+public class StackByArray {
|
|
|
+ public static void main(String[] args) {
|
|
|
+ String exps = "12+8*9-9/3";
|
|
|
+ //索引,用来读取字符串中的元素
|
|
|
+ int index = 0;
|
|
|
+ //保存读取到的数字和符号
|
|
|
+ int number1 = 0;
|
|
|
+ int number2 = 0;
|
|
|
+ int thiChar = ' ';
|
|
|
+ // 拼接字符串
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ // 数字栈
|
|
|
+ ArrayStack numberStack = new ArrayStack(10);
|
|
|
+ // 符号栈
|
|
|
+ ArrayStack operationStack = new ArrayStack(10);
|
|
|
+ // 保存计算结果
|
|
|
+ int result;
|
|
|
+
|
|
|
+ for (index = 0; index < exps.length(); index++) {
|
|
|
+ thiChar = exps.charAt(index);
|
|
|
+ // 判断字符是不是运算符
|
|
|
+ if (operationStack.isOperation(thiChar)){
|
|
|
+ // Todo 比较运算符之间的优先级
|
|
|
+ if (operationStack.comparePriority(thiChar)){
|
|
|
+ // 入栈的运算符大于栈顶的,直接入栈
|
|
|
+ operationStack.push(thiChar);
|
|
|
+ }else{
|
|
|
+ // 入栈的运算符小于栈顶的,将数字栈顶的两个元素进行入栈运算符计算
|
|
|
+ // 栈顶运算符
|
|
|
+ int popChar = operationStack.pop();
|
|
|
+ // 取出数字栈顶的两个元素
|
|
|
+ number2 = numberStack.pop();
|
|
|
+ number1 = numberStack.pop();
|
|
|
+ // 计算结果
|
|
|
+ result = operationStack.calculation(number1, number2, popChar);
|
|
|
+ // 将入栈的运算符入符号栈
|
|
|
+ operationStack.push(thiChar);
|
|
|
+ // 将计算的结果放入数字栈顶
|
|
|
+ numberStack.push(result);
|
|
|
+ }
|
|
|
+ // 数字直接添加到数字栈中
|
|
|
+ }else{
|
|
|
+ while (thiChar >= '0' && thiChar <= '9'){
|
|
|
+ // 数字有可能会是多为,12
|
|
|
+ sb.append(thiChar - '0');
|
|
|
+ System.out.println("拼接字符串"+sb);
|
|
|
+ index++;
|
|
|
+ // 到了最后一位结束
|
|
|
+ if (index >= exps.length()){
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ thiChar = exps.charAt(index);
|
|
|
+ }
|
|
|
+ int num = Integer.parseInt(sb.toString());
|
|
|
+ numberStack.push(num);
|
|
|
+ // 初始化sb
|
|
|
+ sb = new StringBuilder();
|
|
|
+ index--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 运算
|
|
|
+ while (!operationStack.isEmpty()){
|
|
|
+ int popChar = operationStack.pop();
|
|
|
+ number2 = numberStack.pop();
|
|
|
+ number1 = numberStack.pop();
|
|
|
+ result = operationStack.calculation(number1,number2,popChar);
|
|
|
+ numberStack.push(result);
|
|
|
+ }
|
|
|
+ System.out.println(numberStack.pop());
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+class ArrayStack {
|
|
|
+ // 栈大小
|
|
|
+ private final int maxSize;
|
|
|
+ // 栈数组
|
|
|
+ int[] stack;
|
|
|
+ // 栈顶指针,默认为-1,添加元素top++
|
|
|
+ private int top;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化栈
|
|
|
+ */
|
|
|
+ public ArrayStack(int maxSize) {
|
|
|
+ this.maxSize = maxSize;
|
|
|
+ stack = new int[this.maxSize];
|
|
|
+ top = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断是否为空,top=-1,说明栈中没有元素
|
|
|
+ *
|
|
|
+ * @return top == -1
|
|
|
+ */
|
|
|
+ public boolean isEmpty() {
|
|
|
+ return top == -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断栈是否满了,
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean isFull() {
|
|
|
+ return top == maxSize - 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加元素
|
|
|
+ *
|
|
|
+ * @param i
|
|
|
+ */
|
|
|
+ public void push(int i) {
|
|
|
+ if (isFull()) {
|
|
|
+ System.out.println("栈满了,请不要再进来了");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ top++;
|
|
|
+ stack[top] = i;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从栈顶取出一个元素
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public int pop() {
|
|
|
+ if (isEmpty()) {
|
|
|
+ System.out.println("栈是空的,请不要在进来取了");
|
|
|
+ throw new EmptyStackException();
|
|
|
+ }
|
|
|
+ int retNum = stack[top];
|
|
|
+ top--;
|
|
|
+ return retNum;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 遍历栈
|
|
|
+ */
|
|
|
+ public void traverse() {
|
|
|
+ for (int thiChar : stack) {
|
|
|
+ System.out.println(thiChar);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断符号优先级
|
|
|
+ *
|
|
|
+ * @param operation
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public int getPriority(int operation) {
|
|
|
+ if (operation == '*' || operation == '/') {
|
|
|
+ return 2;
|
|
|
+ } else if (operation == '+' || operation == '-') {
|
|
|
+ return 1;
|
|
|
+ } else if (operation >= '0' && operation <= '9') {
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 比较符号栈和入栈符号元素的优先级
|
|
|
+ *
|
|
|
+ * @param operation
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean comparePriority(int operation) {
|
|
|
+ if (isEmpty()) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ int priority1 = getPriority(operation);
|
|
|
+ int priority2 = getPriority(stack[top]);
|
|
|
+ return priority1 > priority2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断输入的是否是一个运算符号
|
|
|
+ *
|
|
|
+ * @param operation
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean isOperation(int operation) {
|
|
|
+ return operation == '*' || operation == '/' || operation == '-' || operation == '+';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算
|
|
|
+ *
|
|
|
+ * @param number1
|
|
|
+ * @param number2
|
|
|
+ * @param operation
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public int calculation(int number1, int number2, int operation) {
|
|
|
+ switch (operation) {
|
|
|
+ case '+':
|
|
|
+ return number1 + number2;
|
|
|
+ case '-':
|
|
|
+ return number1 - number2;
|
|
|
+ case '*':
|
|
|
+ return number1 * number2;
|
|
|
+ case '/':
|
|
|
+ return number1 / number2;
|
|
|
+ default:
|
|
|
+ System.out.println(operation);
|
|
|
+ throw new RuntimeException("符号读取错误!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|