利用栈实现算术表达式求值(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 ...
随机推荐
- ios之如何删除默认的约束
应用场景,你是否尝试过定义一个在设置了autolayout中的xib的控件,然后连线关联了outlet.跟住在代码中设置了针对这个控件的约束,但是发现没有显示效果,控制台里面打印出约束的问题.大概就是 ...
- old header
海纳百川 山不拒土 No Backspace in Real Life. Love Life![Cloud][LBS][GIS][GPS][MAPS][C++][Java]
- Linux下查看mysql、apache是否安装,安装,卸载等操作
Linux下查看mysql.apache是否安装,并卸载. 指令 ps -ef|grep mysql 得出结果 root ? :: /bin/sh /usr/ ...
- 错误名称:EntityCommandExecutionException
错误名称:EntityCommandExecutionException 错误时间:2015/9/22 11:13:34 错误消息:执行命令定义时出错.有关详细信息,请参阅内部异常. 堆栈信息: 在 ...
- 怎样用UltraISO制作U盘系统安装盘
http://jingyan.baidu.com/article/d169e186800f02436711d87b.html 如今用u盘装系统成为主流,如何不被社会淘汰.跟我往下边看吧~~ 工具/原料 ...
- CSV - 操作比较
在数据报表生成的时候,我们一般会用程序去生成CSV.其中有些需要注意的地方. log_file = open('delay.%s.csv' % s_end, 'w') log_file.write(' ...
- Raw-OS源代码分析之消息系统-Queue_Size
分析的内核版本号截止到2014-04-15.基于1.05正式版.blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现"???"字样,则是未深究理解部分. Raw-OS官方 ...
- Supervisor 的配置与使用
环境:ubuntu 14.04 lts http://supervisord.org/liunx 下有很多守护进程的工具,如 nohup,screen,supervisor 等,supervisor ...
- Spark1.0新特性-->Spark SQL
Spark1.0出来了,变化还是挺大的,文档比以前齐全了,RDD支持的操作比以前多了一些,Spark on yarn功能我居然跑通了.但是最最重要的就是多了一个Spark SQL的功能,它能对RDD进 ...
- 【工作代码】复杂 JSON 值替换处理
总结下最近的工作遇到的点:入参复杂 JSON 层层嵌套,Java 怎么优雅的处理. 一.关于 JSON JSON 是类似 XML 用于存储和交互文本信息.但优于 XML ,其更小,更快,更易懂和解析. ...