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 ...
随机推荐
- python装饰器拦截方法执行
import time def log(delay=0): def decorator(func): def wrapper(*args, **kwargs): """我 ...
- W04 散文周刊 : 重回Emacs
W04 散文周刊 : 重回Emacs 邮箱:ppbhoy@qq.com 博客地址: www.pipihao.com 公纵号:南湖小皮 公告:后面会开始稳定更新 使用Emacs还是有些沉重,我一直将Em ...
- ES字段类型
1 String ELasticsearch 5.X之后的字段类型不再支持string,由text和keyword取代,不做说明. 2 text和keyword 2.1 简介 ElasticSearc ...
- 真正“搞”懂HTTPS协议17之TLS握手
经过前两章的学习,我们知道了通信安全的定义以及TLS对其的实现~有了这些知识作为基础,我们现在可以正式的开始研究HTTPS和TLS协议了.嗯--现在才真正开始. 我记得之前大概聊过,当你在浏览器的地址 ...
- Ubuntu18.04编译ZLMediakit支持webrtc
背景 最近在做流媒体相关的一些东西, 比较了一些开源的流媒体服务, 目前 srs 和 ZlmediaKit 项目是评价比较高的, 今天主要在 Ubuntu18.04 上编译 ZlmediaKit, 并 ...
- 【TS】联合类型--类型断言--类型推断
联合类型 在实际开发中,我们接收的变量可能不是一个固定的数据类型,而是动态的多个数据类型,此时用单个固定的数据类型去接收很明显是不行的,为了解决这种可能会接收多个不同数据类型的变量就需要用到联合类型. ...
- 推荐一款新的自动化测试框架:DrissionPage!
今天给大家推荐一款基于Python的网页自动化工具:DrissionPage.这款工具既能控制浏览器,也能收发数据包,甚至能把两者合而为一,简单来说:集合了WEB浏览器自动化的便利性和 request ...
- 挖矿僵尸网络蠕虫病毒kdevtmpfsi处理过程
背景: pgsql连接时候报错org.postgresql.util.PSQLException: FATAL: sorry, too many clients already, 意思是client已 ...
- 理解JS函数之call,apply,bind
前言 在 JavaScript 中,apply.bind 和 call 是三个重要的函数,它们都是 Function.prototype 的方法.这些函数可以让我们动态地改变函数的 this 值,或者 ...
- Layui 表单元素考到页面样式不生效
表单元素必须要标记在表单里面(calss="layui-form") 例如: <div class="layui-form"> <input ...