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 ...
随机推荐
- SpringBoot 学习 step.3数据库
数据库 JPA默认用的是Hibernate. SpringBoot开发WEB应用时,目前菜用较多的是mybatis+mybatis-plus,还有是springboot-data-jpa,jpa默认使 ...
- tomcat报错:java.io.IOException: No space left on device
1 简介 今天网站很多页面访问突然就404了,路径分明没有变,是正确的,就很奇怪 排查日志发现报错java.io.IOException: No space left on device 这个错误,是 ...
- .NET Core 日志记录程序和常用日志记录框架
本文主要内容为.NET Core的日志记录程序和常使用的日志记录框架的简单使用 首先,打开VS2019新建一个ASP.NET Core Web Api项目,项目创建好后会有一个集成好的天气预报的类和控 ...
- 树莓派VNC复制粘贴
1.安装sudo apt install autocutsel 2.运行autocutsel -f
- LoginServlet类
import cn.itcast.dao.UserDao; import cn.itcast.domain.User; import javax.servlet.ServletException; i ...
- Nextcloud的一些错误提示
Nextcloud的一些错误提示 PHP 内存限制低于建议值 512MB 您可以通过以下步骤增加PHP内存限制: 打开php.ini文件 在终端中输入以下命令打开php.ini文件: bash sud ...
- LeetCode-587 安装栅栏及三种凸包算法的学习
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/erect-the-fence 题目描述 在一个二维的花园中,有一些用 (x, y) 坐标表示的树 ...
- 四,redis6版本的使用部署
继第三章(https://www.cnblogs.com/123456likun/p/13841540.html) 官网发布最新的6版本,有新的数据类型出现,给了小编我极大的动力,决定写几张关于最新的 ...
- api规范PHP,RESTful API规范(详细版)
rest 是一种软件架构风格,如果你们的接口是 rest 接口,那么就可被认为你们的的接口是restful的,英文名词和形容词的区别. rest 接口是围绕"资源"展开的,利用HT ...
- I2C接口(续一)
I2C接口共涉及到18个寄存器,下面就来对它们进行具体分析. 先来看I2C配置寄存器CFG,下表是它的全部位结构,其地址分别为0x40050000(I2C0),0x40054000(I2C1),0x4 ...