利用栈实现算术表达式求值(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语言描述)的更多相关文章

  1. Dijkstra的双栈算术表达式求值算法

    这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...

  2. 算法手记(2)Dijkstra双栈算术表达式求值算法

    这两天看到的内容是关于栈和队列,在栈的模块发现了Dijkstra双栈算术表达式求值算法,可以用来实现计算器类型的app. 编程语言系统一般都内置了对算术表达式的处理,但是他们是如何在内部实现的呢?为了 ...

  3. 栈的一个实例——Dijkstra的双栈算术表达式求值法

    Dijkstra的双栈算术表达式求值法,即是计算算术表达式的值,如表达式(1 + ( (2+3) * (4*5) ) ). 该方法是 使用两个栈分别存储算术表达式的运算符与操作数 忽略左括号 遇到右括 ...

  4. [Java]算术表达式求值之三(中序表达式转二叉树方案 支持小数)

    Entry类 这个类对表达式的合法性进行了粗筛: package com.hy; import java.io.BufferedReader; import java.io.IOException; ...

  5. 【算法】E.W.Dijkstra算术表达式求值

    算术表达式求值 我们要学习的一个栈的用例同时也是展示泛型的应用的一个经典例子,就是用来计算算术表达式的值,例如 ( 1 + ( ( 2 + 3 ) * ( 4 * 5 ) ) ) 如果将4乘以5,把3 ...

  6. page80-栈用例-算术表达式求值

    表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时 ...

  7. OpenJudge计算概论-简单算术表达式求值

    /*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...

  8. java实现算术表达式求值

    需要根据配置的表达式(例如:5+12*(3+5)/7.0)计算出相应的结果,因此使用java中的栈利用后缀表达式的方式实现该工具类. 后缀表达式就是将操作符放在操作数的后面展示的方式,例如:3+2 后 ...

  9. [Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

    Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOEx ...

随机推荐

  1. linux shell 多线程执行程序

    Shell中并没有真正意义的多线程,要实现多线程可以启动多个后端进程,最大程度利用cpu性能. 直接看代码示例吧. (1) 顺序执行的代码 #!/bin/bash date ` do { echo & ...

  2. linux crontab 文件位置和日志位置

    一.文件位置 位置一般在/var/spool/cron/下,如果你是root用户,那下面有个root文件,建议日常备份,避免误删除导致crontab 文件丢失: 二.日志文件位置 默认情况下,cron ...

  3. 写给程序员和UI--Android的切图标准

    最近总是有人在问我,Android怎么切图啊,怎么适配啊,不只是Android同行,还有很多新手ui设计师. 于是我就写篇文章,根据我们平时的开发经验,简单的介绍一下吧. 如果UI设计师以1920*1 ...

  4. Windows搭建SVN

    1.服务器下载 VisualSVN 地址:http://subversion.apache.org/packages.html 2.然后下载TortoiseSVN客户端,如果要下中文语言包 也在这个页 ...

  5. web项目总结

    web项目 Webroot下面的index.jsp页面的内容: <%@ page language="java" pageEncoding="UTF-8" ...

  6. 编译fresco源码

    同步发表于http://avenwu.net/fresco/2015/05/07/build_fresco_sample fresco出来已经有一阵子了,曾经尝试过一次clone源码编译,主要是看其自 ...

  7. Win8.1 远程桌面 凭据无法工作

    最近遇到一个杯具的事情 电脑重装完系统后,发现 win7/server08/server12 无法远程到我的电脑了- 每次连接都显示如下:   灵异的是从 xp 和 server03 能远程进来-   ...

  8. Console中加入招聘等个性化信息

    try { if (window.console && window.console.log) { console.log("%c XX息科技 ", "f ...

  9. spring中@param和mybatis中@param使用差别

    spring中@param /** * 查询指定用户和企业关联有没有配置角色 * @param businessId memberId * @return */ int selectRoleCount ...

  10. js多线程?

    http://www.cnblogs.com/o--ok/archive/2012/11/04/JS.html http://blog.csdn.net/nx8823520/article/detai ...