更新了代码,能跑通了,昨天果然是太晚了脑子混了,今天一看其实就差一句,在最后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栈实现计算器的更多相关文章

  1. 深入理解Java虚拟机(第三版)-13.Java内存模型与线程

    13.Java内存模型与线程 1.Java内存模型 Java 内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到主内存和从内存中取出变量值的底层细节 该变量指的是 实例字 ...

  2. 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈

    最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...

  3. java栈内存堆内存和GC相关

    java栈内存堆内存 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存,有着不同的作用.栈内存用来存储局部变量和方法调用.栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属 ...

  4. JAVA栈帧

    简介 Java栈是一块线程私有的内存空间.java堆和程序数据相关,java栈就是和线程执行密切相关的,线程的执行的基本行为是函数调用,每次函数调用的数据都是通过java栈来传递的. Java栈与数据 ...

  5. java虚拟机 jvm 出入java栈 栈空间内存分配

    java栈空间是一块线程私有的内存空间,java堆和程序数据密切相关,那么java栈就是和线程执行密切相关.线程最基本的执行行为就是函数的调用.每次函数调用其实是通过java栈传递数据的. 数据结构中 ...

  6. java虚拟机 jvm java堆 方法区 java栈

    java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...

  7. java 栈 最大深度

      1. 概述 某公司面试,总监大叔过来,问了图论及栈的最大深度,然后^_^ 一直记着,今天搞一下 2. 代码 package com.goodfan.test; public class JavaS ...

  8. 【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 ...

  9. Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用

    ylbtech-Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用 1.返回顶部 1. Java 实例 - for 和 foreach循环使用 ...

  10. Java-Runoob-高级教程-实例-数组:13. Java 实例 – 数组交集

    ylbtech-Java-Runoob-高级教程-实例-数组:13. Java 实例 – 数组交集 1.返回顶部 1. Java 实例 - 数组交集  Java 实例 以下实例演示了如何使用 reta ...

随机推荐

  1. 【学习日志】MySQL分表与索引的关系

    什么情况下需要分表呢?分表又能解决什么问题呢? 一般情况下分表的直接原因是数据量太大了,比如一张表一共只有1w条数据,确实没必要分表.为什么数据量大了就需要分表呢?首先得看看数量量过大后会带来什么问题 ...

  2. ASP.NET Core - .NET 6 的入口文件

    自从.NET 6 开始,微软对应用的入口文件进行了调整,移除了 Main 方法和 Startup 文件,使用顶级语句的写法,将应用初始化的相关配置和操作全部集中在 Program.cs 文件中,如下: ...

  3. 限流器算法实现(JUC原子类使用实践)

    系列文章目录和关于我 一丶限流器存在的意义 在高并发系统中,出于系统保护角度考虑,通常会对流量进行限流. 限流*的目的是在遇到流量高峰期或者流量突增(流量尖刺)时,通过对流量速率进行限制,当达到限制速 ...

  4. C# File、FileInfo、Directory、DirectoryInfo

    本文主要介绍文件类.文件信息类.目录类.目录信息类的常用属性和方法 1.File(文件类) // 1.判断文件是否存在 bool isFileExist = File.Exists(@"D: ...

  5. IOS12.0 + Xcode 12.0 错误:Building for iOS Simulator, but the linked and embedded framework 'XXX.framework' was built for iOS + iOS Simulator

    环境:IOS12.0 + Xcode 12.0 问题描述:运行编译 Building for iOS Simulator, but the linked and embedded framework ...

  6. flask服务器 + 协程 + 爬虫 + ui自动化

    公司有个爬取的需求,要求持续性爬取,需要永久性地挂载到目标网站上,每天爬一次里面的数据.数据有下载表格的,我通过ui自动化点击拿到数据:还有一部分数据是几乎所有的图片信息,信息量近百万,这部分用scr ...

  7. MRI炎症和结构损伤指标对TNF拮抗剂治疗AS患者获持续缓解的预测价值

    MRI炎症和结构损伤指标对TNF拮抗剂治疗AS患者获持续缓解的预测价值 EULAR2015; PresentID: OP0043 PREDICTORS OF SUSTAINED REMISSION O ...

  8. js循环判断创建新对象放数组中

    原效果 之后效果: <!doctype html> <html lang="en"> <head> <meta charset=" ...

  9. java 转发重定向

    首先我们要知道: (1)request.getRequestDispatcher()是请求转发,前后页面共享一个request ; 这个是在服务端运行的,对浏览器来说是透明的.(2)response. ...

  10. MySQL单节点变更为主从节点

    环境说明: 操作系统:CentOS 7.6 数据库版本:5.7 为了实验方便,同一台主机部署了两个实例,3306.3307 部署方案可参考 MySQL多实例部署:mysql多实例部署 - 太阳的阳ฅ ...