1.Java数组模拟栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| package com.datastructure.stack;
import java.util.Scanner;
public class StackTest { public static void main(String[] args) { Stack stack = new Stack(10); String key = ""; boolean loop = true; Scanner scanner = new Scanner(System.in); while(loop){ System.out.println("show:表示显示栈"); System.out.println("push:表示压入栈"); System.out.println("pop:表示出栈"); System.out.println("exit:退出程序"); System.out.println("请输入你的选择"); key = scanner.next(); switch(key){ case "show": stack.showStack(); break; case "push": System.out.println("请输入一个要入栈的数:"); int num = scanner.nextInt(); stack.push(num); System.out.println("入栈成功!"); break; case "pop": System.out.println("出栈的数据是:" + stack.pop()); break; case "exit": loop = false; break; default: System.out.println("输入格式不正确!"); break; } } } }
class Stack { private int maxSize; private int[] stack; private int top = -1;
public Stack(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()){ System.out.println("栈空"); return -1; } int value = stack[top]; top--; return value; } public void showStack(){ if(isEmpty()){ System.out.println("没有数据"); return; } for(int i = top; i >= 0; i--){ System.out.printf("stack[%d]=%d\n",i,stack[i]); } } }
|
2.栈实现综合计算器
- 思路分析:
- 通过一个index值遍历表达式
- 如果发现index扫描到的是一个数字,将该数字入数栈
- 如果Index扫描到的是一个符号:
- 如果当前符号栈为空,直接入符号栈
- 如果符号栈中有操作符,进行比较:
- 如果当前符号的优先级低于或等于栈中的操作符:
- 从数据栈中pop出两个数
- 从符号栈中pop出一个符号
- 进行运算,将得到的结果存入数栈
- 把当前的符号入符号栈
- 如果当前符号优先级高于符号栈中的符号,直接入符号栈
- 当表达式扫描完毕,顺序地从数栈和符号栈中pop出相应的数和符号进行运算
- 最后的数栈中只有一个数字,就是表达式的结果
- 代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
| package com.datastructure.stack;
import java.util.Scanner;
public class StackCalculator { public static void main(String[] args) { String expression = ""; Scanner scanner = new Scanner(System.in); expression=scanner.nextLine(); Stackk nStackk = new Stackk(20); Stackk oStackk = new Stackk(10); int index = 0; int num1 = 0; int num2 = 0; int oper = 0; int res = 0; char ch =' '; String keepNum = ""; while(true){ ch = expression.substring(index,index+1).charAt(0); if(oStackk.isOper(ch)){ if(!oStackk.isEmpty()){ if(oStackk.priority(ch) <= oStackk.priority(oStackk.top())){ num2 = nStackk.pop(); num1 = nStackk.pop(); oper = oStackk.pop(); res = nStackk.cal(num1,num2,oper); nStackk.push(res); oStackk.push(ch); }else{ oStackk.push(ch); } }else{ oStackk.push(ch); }
}else { keepNum += ch; if (index == expression.length() - 1) { nStackk.push(Integer.parseInt(keepNum)); } else { if (oStackk.isOper(expression.substring(index + 1, index + 2).charAt(0))) { nStackk.push(Integer.parseInt(keepNum)); keepNum = ""; } } } index++; if(index >= expression.length()){ break; } } while(true){ if(oStackk.isEmpty()){ break; } else { num2 = nStackk.pop(); num1 = nStackk.pop(); oper = oStackk.pop(); res = nStackk.cal(num1, num2, oper); nStackk.push(res);
} } System.out.println("最后的计算结果为:" + expression + "=" + nStackk.pop()); }
}
class Stackk { private int maxSize; private int[] stack; private int top = -1;
public Stackk(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()){ System.out.println("栈空"); return -1; } int value = stack[top]; top--; return value; } public int top(){ int value = stack[top]; return value; } public void showStack(){ if(isEmpty()){ System.out.println("没有数据"); return; } for(int i = top; i >= 0; i--){ System.out.printf("stack[%d]=%d\n",i,stack[i]); } } public int priority(int oper){ if(oper == '*' || oper == '/'){ return 1; } else 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 oper){ int res = 0; switch(oper){ case '+': res = num1 + num2; break; case '-': res = num1 - num2; break; case '*': res = num1 * num2; break; case '/': res = num1 / num2; break; default: break; } return res; } }
|
3.前缀、中缀、后缀表达式
3.1 前缀表达式
又称波兰表达式, 前缀表达式的运算符位于操作数之前
- 前缀表达式的计算机求值:
- 从右至左扫描表达式,遇到数字时将数字压入栈遇到运算符时弹出栈顶的两个数,用运算符对他们做相应的计算,将结果入栈,重复上述操作直到表达式最左端,最后运算得出的值即为表达式的结果
3.2 中缀表达式
中缀表达式就是我们常见的数字和运算符结合在一起的表达式
- 求值:
- 在计算结果时往往会将中缀表达式转成其他表达式来操作(一般转成后缀表达式)
3.3 后缀表达式
也称逆波兰表达式,与前缀表达式相似,运算符位于操作数字后面
如(3+4)x5-6的后缀表达式为:34+5*6-
- 计算机求值:
- 从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对他们做出相应的计算,并将结果入栈,重复上升哦成直到表达式的最右端
4.逆波兰计算器的实现
4.1 实现思路:
4.2 代码实现:
5.中缀表达式转后缀表达式
5.1 转换的具体步骤:
- 初始化两个栈:运算符栈S1和存储中间结果的栈S2
- 从左至右扫描中缀表达式
- 遇到操作数时,将其压入S2
- 遇到运算符时,比较其与S1栈顶运算符的优先级
- 如果S1为空,或栈顶运算符为左括号”(“,则直接将次运算符入栈;
- 否则,若优先级比栈顶的运算符的优先级高,也将运算符压入S1
- 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符比较
- 遇到括号时:
- 如果是左括号,则直接压入s1
- 如果是右括号,则一次弹出s1栈顶的运算符,并压入s2,直到遇到左括号位置,此时将这一对括号丢弃
- 重复步骤2-5,直到表达式的最右端‘
- 将s1中剩余的运算符一次弹出并压入s2
- 一次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式
5.2 代码实现