栈的应用-表达式求值

硅谷探秘者 1508 0 0

栈的应用-表达式求值

1.概念:

表达式包括 { 前缀表达式(波兰式)、中缀表达式后缀表达式(逆波兰式)}

例如:(a+b)*(a-b)

前缀表达式:*+ab-ab

中缀表达式:(a+b)*(a-b)

后缀表达式:ab+ab-*


        高级语言中采用自然语言的中缀表达式,但是计算机对中缀表达式的处理是非常困难的,而对后缀或前缀表达式则显得非常简单

后缀表达式的特点:

1.在后缀表达式中,变量(操作数)出现的顺序与中缀表达式出现的顺序相同

2.后缀表达式中不需要括号规定计算顺序,而由运算符的位置来确定运算顺序


2.中缀表达式转后缀表达式

例:(a+b)*(a-b) -> ab+ab-*


算法:

1.对中缀表达式从左至右依次扫描,由于操作数的顺序不变,当遇到操作数的时候直接输出;

2.为调整运算顺序,设立一个栈用以保存操作符,扫描到操作符时,将操作符压入栈中

进栈的原则是保持栈顶的操作符的优先级要高于栈中其他操作符的优先级,否则,将栈顶的操作符依次出栈并输出,直到满足要求为止

3.遇到"("时进栈,当遇到")"时,出栈输出,直到遇到")"为止


3.由后缀表达式计算表达式的值

算法:

对后缀表达式从左至右依次扫描,遇到操作数时,将操作数进栈保存

当遇到操作符时,从栈中弹出两个操作数并进行运算,将运算的结果进栈保存;直到表达式结束,栈中唯一的元素即为表达式的值


代码:

只支持 + - / * ( )的大于 0 小于 10 的整数运算

如果想看更加完整的代码请看文章:http://www.jiajiajia.club/weblog/blog/artical/28

package problem;

import java.util.Stack;

/**
 * 表达式计算
 * @author LENOVO
 *
 */
public class Test1 {
	public static void main(String[] args) {
		String mid="(4+2)*(2-1)+8+(1*2)";
		String sub=midToSub(mid);
		System.out.println(sub);
		System.err.println(count(sub));
	}
	/**
	 * 中序表达式转后续表达式
	 * @return
	 */
	public static String midToSub(String mid) {
		Stack<Character> stack=new Stack<>();
		String sub="";
		char c;
		for(int i=0;i<mid.length();i++) {
			c=mid.charAt(i);
			if(c>='0'&&c<='9') {//操作数
				sub+=c;
			}else{//操作符
				if(c=='*'||c=='/') {//*/
					stack.push(c);
				}else if(c=='+'||c=='-') {//+-
					while(!stack.empty()&&(stack.peek()=='*'||stack.peek()=='/')) {
						sub+=stack.pop();
					}
					stack.add(c);
				}else if(c=='(') {//(
					stack.add(c);
				}else if(c==')'){//)
					while(!stack.empty()&&stack.peek()!='(') {
						sub+=stack.pop();
					}
					stack.pop();
				}
			}
		}
		while(!stack.empty()) {//所有的元素出栈
			sub+=stack.pop();
		}
		return sub;
	}
	
	public static int count(String sub) {
		Stack<Integer> stack=new Stack<>();
		Character c;
		Integer a;
		Integer b;
		for(int i=0;i<sub.length();i++) {
			c=sub.charAt(i);
			if(c>='0'&&c<='9') {
				stack.add(Integer.valueOf(c.toString()));
			}else{
				if(c=='+') {
					stack.add(stack.pop()+stack.pop());
				}else if(c=='-') {
					a=stack.pop();
					b=stack.pop();
					stack.add(b-a);
				}else if(c=='*') {
					stack.add(stack.pop()*stack.pop());
				}else{
					a=stack.pop();
					b=stack.pop();
					stack.add(b/a);
				}
			}
		}
		return stack.pop();
	}
	
}

image.png


评论区
请写下您的评论...
暂无评论...
猜你喜欢
数据结构与算法 8373 1.问题描述:问题:上面有一个迷宫,灰色部分代不能通过,白色部分代可以通过,现在从a点出发,能否找到一条路径到b点,如果能,输出此路径。下面采试探法解,采结构保存每一步内容(包括坐标
数据结构与算法 3036 后续计算器核心算法:1.前缀转后缀-开始扫描:2·元素为数字时,加入后缀;3·元素为运算符:a.若为'(',入;、b.若为')',则依次把运算符加入后缀中,直
数据结构与算法 2977 操作c++描述基于双向链//节点classnode{public:intdata;node*next;node*prev;};//双向链#include"node.h
java基础 1921 java正则过滤去除特殊字符publicstaticvoidmain(String[]args){longl=System.currentTimeMillis();StringregEx
weblog 1838 vue-数据绑定-事件绑定!DOCTYPEhtmlhtml head metacharset="UTF-8" title/title scriptsrc="https
前端 1057   例如有一个含有固定格字符串,/test/zzh/00a7700/dev/invock,而且/zzh/和它下一个/是一个一个固定格。那么想获取/zzh/和它下一个/之间内容方法如下
weblog 1983 java正则只能输入6-20位数字或字母[a-zA-Z0-9]{6,20}$
工具 1596 java正则同时验证手机号或电话号码importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassPhone
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。