只能实现个位数的运算

    1. package com.atguigu.stack;
    2. import java.util.Scanner;
    3. /**
    4. * 用栈实现计算器,不能处理多位数运算
    5. * @author Dxkstart
    6. * @create 2021-10-08-17:45
    7. */
    8. public class Calculator {
    9. public static void main(String[] args) {
    10. Scanner scanner = new Scanner(System.in);
    11. System.out.println("请输入计算式:");
    12. String expression = scanner.next();
    13. //创建两个栈,数栈、符号栈
    14. ArrayStack2 numStack = new ArrayStack2(10);
    15. ArrayStack2 operStack = new ArrayStack2(10);
    16. //定义需要的相关变量
    17. int index = 0;//用于扫描
    18. int num1 = 0;
    19. int num2 = 0;
    20. char oper = ' ';
    21. int res = 0;//存放结果
    22. char ch = ' ';//将每次扫描得到的char保存到ch
    23. //开始while循环的扫描expression
    24. while (true){
    25. //依次得到expression的每一个字符
    26. ch = expression.substring(index,index+1).charAt(0);
    27. //判断ch是什么,然后做相应的处理
    28. if (operStack.isOper(ch)){//如果是运算符
    29. //判断当前的符号栈是否为空
    30. if (!operStack.isEmpty()){
    31. //如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,
    32. //再从符号栈中pop出一个符号,进行运算,将的到的结果,入数栈,然后将当前的操作符入符号栈
    33. if (operStack.priority(ch) <= operStack.priority(operStack.peek())){//当前的操作符的优先级小于或者等于栈中的操作符
    34. num1 = numStack.pop();
    35. num2 = numStack.pop();
    36. oper = (char) operStack.pop();
    37. //计算
    38. res = numStack.cal(num1, num2, oper);
    39. numStack.push(res);
    40. //将当前的操作符入符号栈
    41. operStack.push(ch);
    42. } else { //当前的操作符的优先级大于栈中的操作符,直接入栈
    43. operStack.push(ch);
    44. }
    45. }else {
    46. //如果为空直接入栈
    47. operStack.push(ch);
    48. }
    49. }else {//不是运算符时
    50. numStack.push(ch - 48);//注意这里的ch是char型,不是int型, '1' = 48
    51. }
    52. //判断结束
    53. index++;
    54. if (index >= expression.length()){
    55. break;
    56. }
    57. }
    58. //当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应数和符号,并运算
    59. while (true){
    60. //如果符号栈为空,则计算到最后的结果,数栈中只有一个数字【结果】
    61. if (operStack.isEmpty()){
    62. break;
    63. }else {
    64. num1 = numStack.pop();
    65. num2 = numStack.pop();
    66. oper = (char) operStack.pop();
    67. //计算
    68. res = numStack.cal(num1, num2, oper);
    69. numStack.push(res);
    70. }
    71. }
    72. System.out.printf("表达式%s = %d",expression,numStack.pop());//输出最终结果
    73. }
    74. }
    75. //定义一个ArrayStack表示栈
    76. class ArrayStack2 {
    77. private int maxSize;//栈的大小
    78. private int[] stack;//数组,数组模拟栈,数据就放在该数组中
    79. private int top = -1;//top表示栈顶,初始化为-1
    80. //构造器
    81. //初始化栈
    82. public ArrayStack2(int maxSize) {
    83. this.maxSize = maxSize;
    84. stack = new int[maxSize];
    85. }
    86. //可以返回当前栈顶的数据,而不是弹出
    87. public int peek(){
    88. return stack[top];
    89. }
    90. //栈满
    91. public boolean isFull() {
    92. return top == maxSize - 1;
    93. }
    94. //栈空
    95. public boolean isEmpty() {
    96. return top == -1;
    97. }
    98. //入栈 - push
    99. public void push(int value) {
    100. //先判断栈是否满
    101. if (isFull()) {
    102. System.out.println("栈满");
    103. return;
    104. }
    105. top++;
    106. stack[top] = value;
    107. }
    108. //出栈 - pop,将栈顶的数据返回
    109. public int pop() {
    110. //先判断是否为空
    111. if (isEmpty()) {
    112. //抛出异常
    113. throw new RuntimeException("栈空");
    114. }
    115. int value = stack[top];
    116. top--;
    117. return value;
    118. }
    119. //显示栈的所有数据【遍历栈】
    120. public void list() {
    121. //先判断是否为空
    122. if (isEmpty()) {
    123. //抛出异常
    124. throw new RuntimeException("栈空");
    125. }
    126. //需要从栈顶开始显示数据
    127. for (int i = top; i >= 0; i--) {
    128. System.out.printf("stack[%d] = %d \n", i, stack[i]);
    129. }
    130. }
    131. //返回运算符的优先级,优先级是程序员来确定的,优先级使用数字表示
    132. //数字越大,优先级就越高。
    133. public int priority(int oper) {
    134. if (oper == '*' || oper == '/'){
    135. return 1;
    136. }else if (oper == '+' || oper == '-'){
    137. return 0;
    138. }else {
    139. return -1;//假定当前的表达式只有 + - * /
    140. }
    141. }
    142. //判断是不是一个运算符
    143. public boolean isOper(char val){
    144. if (val == '+' || val == '-' || val == '*' || val == '/'){
    145. return true;
    146. }else {
    147. return false;
    148. }
    149. }
    150. //计算方法
    151. public int cal(int num1,int num2,char oper){
    152. int res = 0;//res用于存放计算的结果
    153. switch (oper){
    154. case '+':
    155. res = num1 + num2;
    156. break;
    157. case '-':
    158. res = num2 - num1;//注意顺序
    159. break;
    160. case '*':
    161. res = num1 * num2;
    162. break;
    163. case '/':
    164. res = num2 / num1;//注意顺序
    165. break;
    166. }
    167. return res;
    168. }
    169. }