目录
在实现综合计数器之前,大家应该先了解一下什么是前中后缀表达式
前缀、中缀和后缀表达式是表示数学表达式的三种不同方式。
前缀表达式(也称为波兰式或前缀记法):操作符位于操作数之前。例如,"+ 2 3"表示加法操作,其中2和3是操作数。
中缀表达式:操作符位于操作数之间。这是我们通常使用的数学表达式表示方式。例如,"2 + 3"表示加法操作,其中2和3是操作数。
后缀表达式(也称为逆波兰式或后缀记法):操作符位于操作数之后。例如,"2 3 +"表示加法操作,其中2和3是操作数。
这三种表达式都可以表示相同的数学运算,只是操作符和操作数的排列顺序不同。在计算机中,后缀表达式常用于数学表达式的求值,因为它可以通过使用栈来进行简单而高效的计算。
本次实现综合计算器就是借助后缀表达式来实现,为了简单起见,我们并不加入()等的符号
定义两个栈,一个栈为数栈(NumStack)用来存放数字,另一个栈为符号栈,用来存放符号
1. 通过一个 index 值(索引),来遍历我们的表达式
2. 如果我们发现是一个数字, 就直接入数栈
3. 如果发现扫描到是一个符号, 就分如下情况
3.1 如果发现当前的符号栈为 空,就直接入栈
3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符, 就需要从数栈中pop出两个数,在从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈, 如果当前的操作符的优先级大于栈中的操作符, 就直接入符号栈.
4. 当表达式扫描完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行.
5. 最后在数栈只有一个数字,就是表达式的结果
我们来举个例子 图解 计算 7*2*2-5+1 = 24
代码量太大,不可能一步一步解析了,上面的过程如果能看懂,并且编程有一定基础,下面代码应该不成问题,代码出处033_尚硅谷_栈实现综合计算器-思路分析(1)_哔哩哔哩_bilibili
大家可以去看看
package 逆波兰计数器;
import StackDemo.StackEmptyException;
import java.util.Arrays;
import java.util.Scanner;
class Test{
public static void main(String[] args) {
String str = "7*2*2-5+1";
ArrayStack numStack = new ArrayStack(10);
ArrayStack operaStack = new ArrayStack(10);
String s = "";
int nums1 = 0;
int nums2 = 0;
int index = 0;
int opera = 0;
char ch = ' ';
while (true) {
ch = str.charAt(index);
// 判断该字符是否是符号
if(operaStack.isOpera(ch)){
// 判断符号栈是否为空
if(!operaStack.isEmpty()){
// 判断优先级
if(operaStack.priority(ch) <= operaStack.priority(operaStack.peek())){
nums1 = numStack.pop();
nums2 = numStack.pop();
opera = operaStack.pop();
int cal = numStack.cal(nums1, nums2, opera);
numStack.push(cal);
operaStack.push(ch);
}else{
operaStack.push(ch);
}
}else{
// 符号栈为空,直接入栈
operaStack.push(ch);
}
}else{
boolean flag = true;// 定义标志位 检查字符串是否达到末尾
// 处理非个位数的情况 如 88 66 这样的数
while (!operaStack.isOpera(ch)) {
s+=ch;
if(index == str.length() -1 ){
numStack.push(Integer.parseInt(s));
flag = false;
break;
}else {
index++;
ch = str.charAt(index);
}
}
if(!flag){
break;
}
numStack.push(Integer.parseInt(s));
s = "";
index--;
}
index++;
if(index>=str.length()){
break;
}
}
while (true) {
if(operaStack.isEmpty()){
System.out.println(str+"="+numStack.pop());
break;
}
nums1 = numStack.pop();
nums2 = numStack.pop();
opera = operaStack.pop();
int cal = numStack.cal(nums1, nums2, opera);
numStack.push(cal);
}
}
}
public class ArrayStack {
private final int capacity;
private int top = -1;
private int[] stack ;
public ArrayStack(int capacity){
this.capacity = capacity;
stack = new int[capacity];
}
// 入栈
public void push(int data){
if(isFull()){
stack = Arrays.copyOf(stack,capacity*2);
}
top++;
stack[top] = data;
}
// 出栈
public int pop(){
if(isEmpty()){
throw new StackEmptyException("队列为空,无法删除元素");
}
int value = stack[top];
top--;
return value;
}
// 查看栈顶的值
public int peek(){
return stack[top];
}
// 制定优先级规则
public int priority(int opera){
if(opera == '*' || opera == '/'){
return 1;
}else if(opera == '+' || opera == '-'){
return 0;
}else{
return -1;
}
}
// 判断是否为运算符
public boolean isOpera(int val){
return val == '+' || val == '-' || val == '*' || val == '/';
}
// 运算方法
public int cal(int num1,int num2,int opera){
return switch (opera) {
case '+' -> num1 + num2;
case '-' -> num2 - num1;
case '*' -> num1 * num2;
case '/' -> num2 / num1;
default -> -1;
};
}
public boolean isFull(){
return top == capacity - 1;
}
public boolean isEmpty(){
return top == - 1;
}
}
关于栈的应用远不止于此,大家也不必全部了解,只要能运用到这种程度,在刷点面试题,应付面试足矣!
文章浏览阅读757次,点赞19次,收藏9次。文字动态特效_html canvas 效果
针对组件业务上的需求,需要给 el-table-column 加上限制,需保证表头在一行展示,部分列的内容要一行展示,自适应单项列的宽度;
Ali-Sentinel-链路控制
message handler
文章浏览阅读4.2k次。环境:vs2019 gmssl 32位编译1、首先新建项目2、在VS的工程设置工程属性(参考连接https://blog.csdn.net/zhonghua_csdn/article/details/99011892)右击工程名 ——> 选择“属性” 在“VC++目录”——> “包含目录”中添加openSSL的include文件(在您安装openssl的文件下) 在“VC++目录”——> “库目录”中添加openSSL的lib文件(在您安装openssl的文件下) 在“._使用c语言调用openssl实现sm4代码
文章浏览阅读73次。来源:http://www.bysjhf.com.cn目前,U盘病毒的情况非常严重,几乎所有带病毒的U盘,根目录里都有一个autorun.inf。右键菜单多了“自动播放”、“Open”、“Browser”等项目。由于我们习惯用双击来打开磁盘,但现在我们双击,通常不是打开U盘,而是让autorun.inf里所设的程序自动播放。所以对于很多人来说相当麻烦。其实Autorun...._linux怎么为windows做autorun免疫
文章浏览阅读1.5k次。Qt Creator 报错:Error while building/deploying project helloworld (kit: Desktop Qt 5.6.2 MinGW 32bit) When executing step "qmake" - zhangjunwu - 博客园 (cnblogs.com)https://www.cnblogs.com/zhangjunwu/p/7417566.html注意:Qt文件路径不要出现中文名字和空格!!!......_error while building/deploying project xianzhazhi (kit: desktop qt 5.12.9 ms
文章浏览阅读1.3k次。Installing packages. This might take a couple of minutes.Installing react, react-dom, and react-scripts with cra-template-typescript...npm ERR! code 1npm ERR! path C:\Users\MHX\Desktop\react-demo\node_modules\canvasnpm ERR! command failednpm ERR! comm_installing packages. this might take a couple of minutes. installing react,
文章浏览阅读1.9w次,点赞43次,收藏214次。关于西电计科本科学习的一些经验分享与资料汇总_西电毕设拿良容易吗
文章浏览阅读279次,点赞9次,收藏3次。项目根目录打开终端,执行以下命令,安装依赖。执行以下命令后,在浏览器中打开。就可以打开这个项目了。
文章浏览阅读8.5k次,点赞4次,收藏24次。关于C++中二维vector使用vector本来就是可以用来代替一维数组的,vector提供了operator[]函数,可以像数组一样的操作,而且还有边界检查,动态改变大小。这里只介绍用它来代替二维的数组,二维以上的可以依此类推。1、定义二维vectorvector<vector<int>> A;//错误的定义方式vector<vector<int> > A;//正缺的定义方式vector<vector<int> > v;/_c++ 二维vector
文章浏览阅读187次。广告关闭腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元!导言:记录下学习的算法题,写练多,脑子才能转的快! 今日算法题:二分法查找说下我对于二分法查找的理解:【和猜数字游戏差不多】 要在一个有序数列中找到一个与对应给定数字。 1、找到有序数列中最中间的数字2、若中间值大于给定值,则在左边数列重新二分查找3、若中间值小于给定值,则在右边数列..._python服务端算法题