利用栈实现算术表达式求值(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. 在C#中如何读取枚举值的描述属性

    在C#中,有时候我们需要读取枚举值的描述属性,也就是说这个枚举值代表了什么意思.比如本文中枚举值 Chinese ,我们希望知道它代表意思的说明(即“中文”). 有下面的枚举: 1 2 3 4 5 6 ...

  2. 忘记hmailiserver邮件服务器后台登陆密码解决

    进入后台进行hmailiserver的相关设置,发现登陆密码忘记了,如下图:

  3. Node-restify 简介

    restify 是Node.js的模块.虽然restify的API或多或少的参考了express,但restify不是一个MVC框架,它是一套为了能够正确构建REST风格API而诞生的框架. http ...

  4. 用户管理 之 Linux 用户(User)查询篇

    用户(User)和用户组(Group)的配置文件,是系统管理员最应该了解和掌握的系统基础文件之一,从另一方面来说,了解这些文件也是系统安全管理的重要组成部份:做为一个合格的系统管理员应该对用户和用户组 ...

  5. C#-DataTable分页代码

    /// <summary> /// DataTable分页并取出指定页码的数据 /// </summary> /// <param name="dtAll&qu ...

  6. Lists in Prolog

    Symbols in Prolog: atom variable number list (how to assembly and take them apart)   Lists are very  ...

  7. A/B测试

    昨天把前段时间开发的二胡调音器的应用发布到了亚马逊应用程序商店,看到了一个A/B测试的标签,了解一下A/B测试的工作原理. A/B测试是一种新兴的网页优化方法,可以用于增加转化率注册率等网页指标. 使 ...

  8. [转]Raspberry Pi做成路由器

    http://raspjason.blog.51cto.com/8565009/1426561/ 曾经看到很多文章把Raspberry Pi制作成无线AP,但是我今天要做的是把Raspberry Pi ...

  9. [译] 二、开始iOS编程之前,你还需要做什么?

    声明:本文翻译自AppCoda网站的文章:What You Need to Begin iOS Programming?,作者是创建者Simon Ng.如有异议,请联系博主.   更新:帖子已经重新被 ...

  10. 15.6.6-sql字符串组装技巧

    组装sql字符串,丢给exec sp_executesql执行 exec sp_executesql N'exec sp_executesql N''select * from TESTTEST.db ...