Java解析字符串表达式--逆波兰表达式的生成
2014-09-11 14:19
232 查看
上回讲了如何计算后缀表达式,其实真正的难点在于如何将一个正常的字符串表达式(中缀表达式)变成一个后缀表达式。如将6 * ( 5 + ( 2 + 3) * 8 + 3)变为6 5 2 3 + 8 * + 3 + *
逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
首先约定表达式中运算符的优先级,从大到小依次为:()、* 和 /、+ 和 -。暂时只考虑四则运算。
顺序读取字符串表达式,规则:
读到的是操作数,直接输出;
读到的是操作符(+-*/)(记为read),将其与栈顶的操作符(记为top)进行优先级比较:read>top,read入栈,继续读下一个;read≤top,top出栈,并输出到list中,read继续和新的top比较;top为空,read直接入栈;若top是“(”,read直接入栈,因为“(”优先级最高;
括号的处理:读到左括号“(”,直接将其压入栈中,并且除非遇到右括号“)”,“(”是不会弹出的;读到右括号“)”,将“(”之上的元素全部依次输出,并弹出“(”但不输出;
准备:一个栈stack暂存运算符,一个list存放输出,仍以6 * ( 5 + ( 2 + 3) * 8 + 3)为例。
读到“6”,直接输出【list:6;stack:】
读到“*”,与栈顶top比较,top为空,“*”入栈【list:6;stack:*】
读到“(”,直接入栈【list:6;stack:*,(】
读到“5”,直接输出【list:6,5;stack:*,(】
读到“+”,与栈顶top比较,“+”<“(”,入栈【list:6,5;stack:*,(,+】
读到“(”,直接入栈【list:6,5;stack:*,(,+,(】
读到“2”,直接输出【list:6,5,2,;stack:*,(,+,(】
读到“+”,与栈顶“(”比较,“+”<“(”,入栈【list:6,5,2,;stack:*,(,+,(,+】
读到“3”,直接输出【list:6,5,2,3,;stack:*,(,+,(,+】
读到“)”,输出“(”之上的元素【list:6,5,2,3,+;stack:*,(,+,】
读到“*”,与栈顶的“+”比较, “*”>“+”,“*”入栈【list:6,5,2,3,+;stack:*,(,+,*,】
读到“8”,直接输出【list:6,5,2,3,+,8,;stack:*,(,+,*,】
读到“+”,与栈顶的“*”比较,“+”<“*”,“*”出栈并输出【list:6,5,2,3,+,8,*;stack:*,(,+,】;
“+”,与栈顶的“+”比较,“+”=“+”,“+”出栈并输出【list:6,5,2,3,+,8,*,+;stack:*,(,】;
“+”,与栈顶的“(”比较,“+”<“(”,“+”入栈【list:6,5,2,3,+,8,*,+;stack:*,(,+】;
读到“3”,直接输出,【list:6,5,2,3,+,8,*,+,3;stack:*,(,+】
读到“)”,输出“(”之上的元素,【list:6,5,2,3,+,8,*,+,3,+;stack:*,】
输出栈中所有剩下的,【list:6,5,2,3,+,8,*,+,3,+,*;stack:,】
最终的后缀表达式就是:6 5 2 3 + 8 * + 3 + *
至此,中缀表达式到后缀表达式的任务已经全部完成!
但是需要注意的是,本文中只是做了当运算数据为个位数的处理,当为多位数时该怎么做呢?
另外当遇到“/”处时,要对被除数进行非0判断;
另外还可以考虑含有负数的运算,含有小数的以及幂运算
那都是数据如何处理的问题了,整体思路应该都差不多!
逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
正常的中缀表示 | 逆波兰表达式 |
a+b | a,b,+ |
a+(b-c) | a,b,c,-,+ |
a+(b-c)*d | a,b,c,-,d,*,+ |
a+d*(b-c) | a,d,b,c,-,*,+ |
顺序读取字符串表达式,规则:
读到的是操作数,直接输出;
读到的是操作符(+-*/)(记为read),将其与栈顶的操作符(记为top)进行优先级比较:read>top,read入栈,继续读下一个;read≤top,top出栈,并输出到list中,read继续和新的top比较;top为空,read直接入栈;若top是“(”,read直接入栈,因为“(”优先级最高;
括号的处理:读到左括号“(”,直接将其压入栈中,并且除非遇到右括号“)”,“(”是不会弹出的;读到右括号“)”,将“(”之上的元素全部依次输出,并弹出“(”但不输出;
准备:一个栈stack暂存运算符,一个list存放输出,仍以6 * ( 5 + ( 2 + 3) * 8 + 3)为例。
读到“6”,直接输出【list:6;stack:】
读到“*”,与栈顶top比较,top为空,“*”入栈【list:6;stack:*】
读到“(”,直接入栈【list:6;stack:*,(】
读到“5”,直接输出【list:6,5;stack:*,(】
读到“+”,与栈顶top比较,“+”<“(”,入栈【list:6,5;stack:*,(,+】
读到“(”,直接入栈【list:6,5;stack:*,(,+,(】
读到“2”,直接输出【list:6,5,2,;stack:*,(,+,(】
读到“+”,与栈顶“(”比较,“+”<“(”,入栈【list:6,5,2,;stack:*,(,+,(,+】
读到“3”,直接输出【list:6,5,2,3,;stack:*,(,+,(,+】
读到“)”,输出“(”之上的元素【list:6,5,2,3,+;stack:*,(,+,】
读到“*”,与栈顶的“+”比较, “*”>“+”,“*”入栈【list:6,5,2,3,+;stack:*,(,+,*,】
读到“8”,直接输出【list:6,5,2,3,+,8,;stack:*,(,+,*,】
读到“+”,与栈顶的“*”比较,“+”<“*”,“*”出栈并输出【list:6,5,2,3,+,8,*;stack:*,(,+,】;
“+”,与栈顶的“+”比较,“+”=“+”,“+”出栈并输出【list:6,5,2,3,+,8,*,+;stack:*,(,】;
“+”,与栈顶的“(”比较,“+”<“(”,“+”入栈【list:6,5,2,3,+,8,*,+;stack:*,(,+】;
读到“3”,直接输出,【list:6,5,2,3,+,8,*,+,3;stack:*,(,+】
读到“)”,输出“(”之上的元素,【list:6,5,2,3,+,8,*,+,3,+;stack:*,】
输出栈中所有剩下的,【list:6,5,2,3,+,8,*,+,3,+,*;stack:,】
最终的后缀表达式就是:6 5 2 3 + 8 * + 3 + *
至此,中缀表达式到后缀表达式的任务已经全部完成!
但是需要注意的是,本文中只是做了当运算数据为个位数的处理,当为多位数时该怎么做呢?
另外当遇到“/”处时,要对被除数进行非0判断;
另外还可以考虑含有负数的运算,含有小数的以及幂运算
那都是数据如何处理的问题了,整体思路应该都差不多!
相关文章推荐
- Java解析字符串表达式--逆波兰表达式的计算
- Java中读取XML文件,生成XML格式的字符串并解析这个字符串
- Java生成和解析XML格式文件和字符串的实例代码
- JSON解析类库之Fastjson(1) --- Fastjson类库学习, 生成与解析json数据,json字符串与Java对象互转
- Java生成和解析XML格式文件和字符串
- Java以DOM方式解析生成xml文件或字符串
- JSON解析类库之Jackson(1) --- Jackson类库学习, 生成与解析json数据,json字符串与Java对象互转
- Java生成和解析XML格式文件和字符串的实例代码
- java中正则表达式用Pattern计算字符串的结果(四则运算);分成有括号和没括号;当然也可以采用逆波兰式
- Java生成和解析XML格式文件和字符串的实例代码
- java正则表达式 分段解析字符串使用(.*?)(?=)
- 用Java模拟通过四则运算表达式字符串,构造逆波兰表达式,计算结果
- 利用java正则表达式来解析并获取指定的字符串
- Java生成和解析XML格式文件和字符串的实例代码
- Java - 注解使用示例(解析注解格式化类生成字符串)
- JSON解析类库之JSON-lib --- JSON-lib类库学习, 生成与解析json数据, json字符串与Java对象互转
- 逆波兰表达式的生成(Java版)
- Java生成和解析XML格式文件和字符串的实例代码【dom4j中的SAXReader对象读取并解析xml文件】
- Java 正则表达式 分组 解析 字符串
- Java生成和解析XML格式文件和字符串的实例代码