利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述)
算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识。声明:部分代码参考自茫茫大海的专栏。
链栈的实现:
package 算数表达式求值;
public class Stack<T> {
//节点类
public class Node{
public T data;
public Node next;
public Node(){}
public Node(T data,Node next){
this.data = data;
this.next = next;
}
}//Node
public Node top = new Node();
public int size;
public Node oldNode;
//入栈
public void push(T element){
top = new Node(element,top);
size++;
}
//出栈
public T pop(){
oldNode = top;
top = top.next;
//oldNode = null;
size--;
return oldNode.data;
}
//返回栈顶对象的数据域,但不出栈
public T peek(){
return top.data;
}
//栈长
public int length(){
return size;
}
//判断栈是否为空
public boolean isEmpty(){
return size == 0;
}
}
表达式求值的实现:
package 算数表达式求值; import java.util.Scanner;
//import java.util.Stack;
public class Expression { //运算符之间的优先级,其顺序是+、-、*、/、(、),其中大于号表示优先级高
//,小于号表示优先级低,等号表示优先级相同,感叹号表示没有优先关系
public static final char[][] relation = {{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},{'<','<','<','<','<','=','!'},
{'>','>','>','>','!','>','>'},{'<','<','<','<','<','!','='}}; public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(true){
try{
System.out.println("请输入要计算的表达式:");
String exp = input.next();
System.out.println(calc(exp + "#"));
}catch(ArithmeticException e1){
System.out.println("表达式中的分母不能为0");
e1.printStackTrace();
}
}
}
/**
*
* @param exp 要计算的表达式
* @return 计算的结果
*/
private static int calc(String exp) {
//操作数栈
Stack<Integer> num = new Stack<Integer>();
//操作符栈
Stack<Character> op = new Stack<Character>(); op.push('#');
int i = 0;
char ch = exp.charAt(i);
boolean flag = false;//判断连续的几个字符是否是数字,若是,就处理成一个数字。这样就能处理多位数的运算了。
while(ch != '#' || op.peek() != '#') {//peek()查看栈顶对象但不移除。
if(ch >= '0' && ch <= '9') {
if(flag) {
int tmp = num.pop();
num.push(tmp * 10 + Integer.parseInt(ch + ""));
} else {
num.push(Integer.parseInt(ch + ""));
}
flag = true;
i++;
} else {
flag = false;
switch(precede(op.peek(), ch)) {
case '<':
op.push(ch);
i++;
break;
case '=':
op.pop();
i++;
break;
case '>':
int num2 = num.pop();
int num1 = num.pop();
int result = operate(num1, op.pop(), num2);
num.push(result);
break;
case '!':
System.out.println("输入的表达式错误!");
return -1;
}
}
ch = exp.charAt(i);
}
return num.peek();
}
private static char precede(char peek, char ch) {
return relation[getIndex(peek)][getIndex(ch)];
} /**
*
* @param ch 操作符
* @return 操作符的索引,按照+、-、*、/、(、)的顺序
*/
private static int getIndex(char ch) {
int index = -1;
switch(ch) {
case '+':
index = 0;
break;
case '-':
index = 1;
break;
case '*':
index = 2;
break;
case '/':
index = 3;
break;
case '(':
index = 4;
break;
case ')':
index = 5;
break;
case '#':
index = 6;
break;
}
return index;
} /**
*
* @param num1 第一个运算数
* @param ch 运算符
* @param num2 第二个运算数
* @return 运算结果
*/
private static int operate(int num1, char ch, int num2) {
int result = 0;
switch(ch) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num1 / num2;
break;
}
return result;
}
}
异常处理有待完善,引用请指明出处。
利用栈实现算术表达式求值(Java语言描述)的更多相关文章
- Dijkstra的双栈算术表达式求值算法
这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...
- 算法手记(2)Dijkstra双栈算术表达式求值算法
这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...
- 栈的一个实例——Dijkstra的双栈算术表达式求值法
Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...
- [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)
Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...
- 【算法】E.W.Dijkstra算术表达式求值
算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...
- page80-栈用例-算术表达式求值
表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时 ...
- OpenJudge计算概论-简单算术表达式求值
/*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...
- java实现算术表达式求值
需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...
- [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...
随机推荐
- 【CUDA学习】共享存储器
下面简单介绍一些cuda中的共享存储器和全局存储器 共享存储器,shared memory,可以被同一块中的所有线程访问的可读写存储器,生存期是块的生命期. Tesla的每个SM拥有16KB共享存储器 ...
- Android 组件系列-----Activity保存状态
本篇随笔将详细的讲解Activity保存状态的概念,也就是saving activity state. 一.Activity状态保持概念 保存Activity的状态是非常重要的,例如我们在玩一个游戏的 ...
- Spark使用总结与分享
背景 使用spark开发已有几个月.相比于python/hive,scala/spark学习门槛较高.尤其记得刚开时,举步维艰,进展十分缓慢.不过谢天谢地,这段苦涩(bi)的日子过去了.忆苦思甜,为了 ...
- [转]mongodb与mysql相比的优缺点
原文地址:http://blog.sina.com.cn/s/blog_966e430001019s8v.html 与关系型数据库相比,MongoDB的优点:①弱一致性(最终一致),更能保证用户的访问 ...
- clearfix清除浮动进化史
我想大家在写CSS的时候应该都对清除浮动的用法深有体会,今天我们就还讨论下clearfix的进化史吧. clearfix清除浮动 首先在很多很多年以前我们常用的清除浮动是这样的. .clear{cle ...
- Sublime Text 使用技巧
之前就一直在用Sublime Text 来作为默认的文本编辑工具,但也只是简单的用用,一些Sublime Text本身的快捷键什么的都没研究过,今天特地在网上看了一下,快捷键比较多,要想熟练运用还得在 ...
- linux 下 取进程占用内存(MEM)最高的前10个进程
# linux 下 取进程占用 cpu 最高的前10个进程ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head # linux 下 取进程占用内存 ...
- Android 6.0 源代码编译实践
http://www.judymax.com/archives/1087 Android 6.0 源代码编译实践 https://mirrors.tuna.tsinghua.edu.cn/help/A ...
- 【黑金原创教程】【FPGA那些事儿-驱动篇I 】连载导读
前言: 无数昼夜的来回轮替以后,这本<驱动篇I>终于编辑完毕了,笔者真的感动到连鼻涕也流下来.所谓驱动就是认识硬件,还有前期建模.虽然<驱动篇I>的硬件都是我们熟悉的老友记,例 ...
- URL 学习总结
1.绝对路径(以"/"斜线开头的路径,代表相对于当前Web应用): a)地址给服务器用,web应用名称可以省略. 请求包含:request.getRequestDispatcher ...