13.java栈实现计算器
更新了代码,能跑通了,昨天果然是太晚了脑子混了,今天一看其实就差一句,在最后while循环的时候忘记把拿到的oper从栈里pop出去了,导致oper栈一直不空就要一直从数据栈中取数据进行计算所以一直在越界。
老师提供的计算器的特点:计算数据要为一位数,先减后加会导致出错。我在修改了将判断oper的函数改为循环后,即一直对比直到栈空或优先级高于栈顶符号才入栈,而非老师的版本只判断一次。保证了其可以先做减法也没有问题。但多位数的bug还未 改,有思路但就要大改了。以后有机会再说吧qwq
——————————————————————————————————————————————————————————————————
今天是大困难的一天,学习了中缀表达式、后缀表达式、前缀表达式的定义以及计算方式,不得不说发明这种方法的人脑子真的太好使。
老师讲了两种计算器,一种是通过数组栈写中缀表达式的计算器,没写出来- -,小分支真的太多太多了,想改善老师的代码的bug最后改到头昏脑胀也没改出来,参考了视频弹幕中的方法,但还是不太可行,明天接着改吧(或者不改了。中缀表达式真的好复杂- -
说起来大二的数据结构课就是从中缀表达式这里开始彻底脱节的,这次倒是确实地明白了几种表达式的计算方式及定义了。
凑合看吧,明天起来继续调试看看能不能调通。
package linkedlist;
public class jisuanqi {
public static void main(String[] args){
String expression="3-2-2";
ArrayStack1 numstack=new ArrayStack1(10);
ArrayStack1 operstack=new ArrayStack1(10);
int index=0;
int num1=0;
int num2=0;
int oper=0;
int res=0;
char ch=' ';
while (true){
ch=expression.charAt(index);
if(operstack.isoper(ch)){
if(operstack.isEmpty()){
operstack.push(ch);
}else {
while (true){
if (operstack.isEmpty()){
operstack.push(ch);
break;
}
if(operstack.priority(ch)<=operstack.priority(operstack.peek())){
num2=numstack.pop();
num1=numstack.pop();
oper=operstack.pop(); //就是这句话。。
res=numstack.cal(num1,num2,oper);
numstack.push(res);
}else {
operstack.push(ch);
break;
}
}
}
}else {
numstack.push(ch-48);
}
index++;
if (index>=expression.length()) break;
}
while(true){
if (operstack.isEmpty()) break;
num2=numstack.pop();
num1=numstack.pop();
oper=operstack.pop();
res=numstack.cal(num1,num2,oper);
numstack.push(res);
}
int res2=numstack.pop();
System.out.println(res2);
}
}
class ArrayStack1{
public int top=-1;
public int[] stack;
public int maxSize;
public ArrayStack1(int maxSize) {
this.maxSize = maxSize;
stack=new int[maxSize];
}
public int peek(){
return stack[top];
}
public int priority(int oper){
if(oper=='*'||oper=='/'){
return 1;
}else if (oper=='+'||oper=='-'){
return 0;
}else {
return -1;
}
}
public boolean isoper(int oper){
return oper=='+'||oper=='-'||oper=='*'||oper=='/';
}
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;
}
return res;
}
public boolean isFull(){
if(top==maxSize-1) return true;
return false;
}
public boolean isEmpty(){
if(top==-1) return true;
return false;
}
public void push(int value){
if(isFull()){
System.out.println("栈满,无法加入");
return;
}
top++;//先加栈顶再赋值
stack[top]=value;
}
public int pop(){
if(isEmpty()){
throw new RuntimeException("栈空,没有数据");
}
int value=stack[top];
top--;
return value;
}
public void list(){
if(isEmpty()){
System.out.println("栈空,没有数据");
}
for(int i=top;i>=0;i--){
System.out.printf("stack[%d]=%d",i,stack[i]);
}
}
}
第二种计算器明显人性化太多了,是后缀表达式的计算器,虽然人类很难看懂是真的,但算起来真的太方便了,很容易就可以复现;
package linkedlist; import java.util.ArrayList;
import java.util.List;
import java.util.Stack; public class caculator {
public static void main(String[] args){
//String suffixExpression="30 4 + 5 * 6 -";
String suffixExpression="4 5 * 8 - 60 + 8 2 / +";
List<String> list=getListString(suffixExpression);
int res=cal(list);
System.out.print(res);
}
public static List<String> getListString(String s){
String[] sp=s.split(" ");
List<String> list=new ArrayList<String>();
for (String c:sp){
list.add(c);
}
return list;
}
public static int cal(List<String> list){
Stack<String> stack=new Stack<String>();
for (String item:list){
if(item.matches("\\d+")){
stack.push(item);
}else {
int num2=Integer.parseInt(stack.pop());
int num1=Integer.parseInt(stack.pop());
int res=0;
if (item.equals("+")){
res=num1+num2;
}else if (item.equals("-")){
res=num1-num2;
}else if(item.equals("/")){
res=num1/num2;
}else if (item.equals("*")){
res=num1*num2;
}else {
throw new RuntimeException("运算符有误");
}
stack.push(""+res);
}
}
return Integer.parseInt(stack.pop());
}
}
13.java栈实现计算器的更多相关文章
- 深入理解Java虚拟机(第三版)-13.Java内存模型与线程
13.Java内存模型与线程 1.Java内存模型 Java 内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到主内存和从内存中取出变量值的底层细节 该变量指的是 实例字 ...
- 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈
最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...
- java栈内存堆内存和GC相关
java栈内存堆内存 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存,有着不同的作用.栈内存用来存储局部变量和方法调用.栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属 ...
- JAVA栈帧
简介 Java栈是一块线程私有的内存空间.java堆和程序数据相关,java栈就是和线程执行密切相关的,线程的执行的基本行为是函数调用,每次函数调用的数据都是通过java栈来传递的. Java栈与数据 ...
- java虚拟机 jvm 出入java栈 栈空间内存分配
java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关.线程最基本的执行行为就是函数的调用.每次函数调用其实是通过java栈传递数据的. 数据结构中 ...
- java虚拟机 jvm java堆 方法区 java栈
java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...
- java 栈 最大深度
1. 概述 某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^ 一直记着,今天搞一下 2. 代码 package com.goodfan.test; public class JavaS ...
- 【Java】-NO.13.Java.1.Foundation.1.001-【Java IO】-
1.0.0 Summary Tittle:[Java]-NO.13.Java.1.Foundation.1.001-[Java IO]- Style:Java Series:Foundation Si ...
- Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用
ylbtech-Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用 1.返回顶部 1. Java 实例 - for 和 foreach循环使用 ...
- Java-Runoob-高级教程-实例-数组:13. Java 实例 – 数组交集
ylbtech-Java-Runoob-高级教程-实例-数组:13. Java 实例 – 数组交集 1.返回顶部 1. Java 实例 - 数组交集 Java 实例 以下实例演示了如何使用 reta ...
随机推荐
- Django-Ajax、form组件
1.Ajax 1.AJAX:不是新的编程语言,而是一种使用现有标准的新方法,我们目前学习的是jQuery版本.特点:异步提交,局部刷新. 2.AJAX 最大的优点是在不重新加载整个页面的情况下,可以与 ...
- 【动画笔记】数据结构-AVL树的插入操作
本笔记前置知识: 二叉搜索(排序)树及其插入操作. 本文主要围绕AVL树的平衡因子.纸上做题思路.失衡类型(LL/RR/LR/RL).失衡调整方法.插入后回溯这几部分知识点展开. 注: 本笔记中的平衡 ...
- Vue23 ref属性
1 简介 在js中,我们获取一个元素可以通过document.getElementById()去获取,在vue中,使用了ref属性来替代id,通过ref属性可以获取html元素以及vue组件实例对象 ...
- 推荐一个分布式单点登录框架XXL-SSO!
有关单点登录(SSO)之前有写过两篇文章 一文读懂 JWT! 看完这篇不能再说不懂SSO原理了! 如果说XXL-JOB你可能并不陌生,它是非常火爆的一个分布式任务调度平台.但其实在该作者还有一个非常优 ...
- 详解神经网络基础部件BN层
摘要:在深度神经网络训练的过程中,由于网络中参数变化而引起网络中间层数据分布发生变化的这一过程被称为内部协变量偏移(Internal Covariate Shift),而 BN 可以解决这个问题. 本 ...
- 与 Flutter 共创未来 | Flutter Forward 活动精彩回顾
作者 / Google 开发者框架和语言 (含 Flutter.Dart 和 Go) 产品经理 & 用户体验总监 Tim Sneath 我们很高兴可以在 Flutter Forward 活动 ...
- LOJ 数列分块入门 6
\(\text{Solution}\) 涉及到插入,分块需要动态维护块内的元素及相对位置 于是妙用 \(\text{vector}\) 学到了 \(insert\) 操作,在某个迭代器前插入元素 这样 ...
- JZOJ 3570. 【GDKOI2014】壕壕的寒假作业
解析 这道题比较水. 求最快什么时候做完作业? 如果要最快完成第i份作业,那么是i的前继那些作业都要完成之后才能够完成i,所以,为了尽快完成i,我们要把i的前继的作业全部先做完. 最慢什么时候做完作业 ...
- php pdo如何查询记录条数
转载php中文网:https://www.php.cn/php-ask-457710.html php pdo查询记录条数的方法:1.使用fetchAll函数查询,其语法如"$rows=$q ...
- postgresql索引使用情况及坏索引处理
1.postgresql中索引系统视图pg_stat_user_indexes TEST=# \d+ sys_stat_user_indexes View "SYS_CATALOG.sys_ ...