后续表达式 计算器
后续表达式 计算器
核心算法:
1.前缀表达式转后缀表达式 ->开始扫描:
2·元素为数字时,加入后缀表达式;
3·元素为运算符:
a. 若为 '(',入栈; 、
b. 若为')',则依次把栈中的的运算符加入后缀表达式中,直到出现'(',从栈中删除'(' ;
c. 若为 除括号外的其他运算符(+ - * /),当其优先级高于除'('以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或者遇到了一个左括号为止。
4.·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;
/***
* 元素类型
* @author LENOVO
*
*/
public enum ElementsType{
NUMBER,OPERATOR
}
/**
* 封装操作元素
* @author LENOVO
*/
public class Elements {
private ElementsType elementsType;//元素类型
private Object obj;//元素值
private Integer level;//元素等级
public Elements(ElementsType elementsType, Object obj, Integer level) {
super();
this.elementsType = elementsType;
this.obj = obj;
this.level = level;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public ElementsType getElementsType() {
return elementsType;
}
public void setElementsType(ElementsType elementsType) {
this.elementsType = elementsType;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
@Override
public String toString() {
return obj.toString()+" ";
}
}
import java.util.LinkedList;
/**
* 核心计算类
* @author LENOVO
*
*/
public class Count {
/**
* 分割操作符与操作数
* @param medStrObj 中序表达式
* @return
*/
public LinkedList<Elements> cutting(String medStr) {
LinkedList<Elements> medExpression=new LinkedList<Elements>();
for(int i=0;i<medStr.length();i++) {
if(i+1==medStr.length()&&(medStr.charAt(i)<='9'&&medStr.charAt(i)>='0')) {
String wait=medStr.substring(0,i+1);
medStr=medStr.substring(i,medStr.length());
Elements e=new Elements(ElementsType.NUMBER,new Double(wait),0);
medExpression.add(e);
break;
}
if((medStr.charAt(i)>='0'&&medStr.charAt(i)<='9')||medStr.charAt(i)=='.') {
continue;
}
char c=medStr.charAt(i);
if(medStr.charAt(i)=='+'||medStr.charAt(i)=='-'||medStr.charAt(i)=='*'||medStr.charAt(i)=='/'
||medStr.charAt(i)==')'||medStr.charAt(i)=='^') {
if(i!=0) {
String wait=medStr.substring(0,i);
medStr=medStr.substring(i,medStr.length());
Elements e=new Elements(ElementsType.NUMBER,new Double(wait),0);
medExpression.add(e);
}
}
String wait=medStr.substring(0,1);
medStr=medStr.substring(1,medStr.length());
i=-1;
Elements e=new Elements(ElementsType.OPERATOR,wait,c=='+'||c=='-'?1:c=='*'||c=='/'?2:c=='^'?3:4);
medExpression.add(e);
}
return medExpression;
}
/***
* 中序表达式转后续表达式
* @param medStrs 中序表达式
* @return
* @throws Exception
*/
public LinkedList<Elements> medTransSub(String medStr)throws Exception{
LinkedList<Elements> medStrObj=cutting(medStr);
LinkedList<Elements> subStrObj=new LinkedList<Elements>();
LinkedList<Elements> stack=new LinkedList<Elements>();
for(int i=0;i<medStrObj.size();i++) {
if(medStrObj.get(i).getElementsType()==ElementsType.NUMBER) {
subStrObj.addLast(medStrObj.get(i));
}else if(medStrObj.get(i).getObj().equals("(")) {
stack.addFirst(medStrObj.get(i));
}else if(medStrObj.get(i).getObj().equals(")")) {
while(true) {
Elements c=(Elements) stack.removeFirst();
if(c.getObj().equals("(")||stack.size()<=0) {
break;
}else {
subStrObj.addLast(c);
}
}
}else {
while(true) {
if((stack.size()<=0||stack.getFirst().getObj().equals("("))
||(medStrObj.get(i).getLevel()>stack.getFirst().getLevel())){
break;
}else {
Elements op=(Elements) stack.removeFirst();
subStrObj.addLast(op);
}
}
stack.addFirst(medStrObj.get(i));
}
}
while(true) {
if(stack.size()<=0) {
break;
}
subStrObj.addLast(stack.removeFirst());
}
System.out.println(subStrObj);
return subStrObj;
}
/**
* 核心计算方法
* @param medStr 中序表达式
* @return
* @throws Exception
*/
public double countCore(String medStr) throws Exception {
LinkedList<Elements> subStrObj=medTransSub(medStr);
LinkedList<Double> numberStack=new LinkedList<Double>();
for(int i=0;i<subStrObj.size();i++) {
Elements e=subStrObj.get(i);
if(e.getElementsType()==ElementsType.NUMBER) {
numberStack.addFirst((Double)e.getObj());
}else {
if(e.getObj().equals("+")) {
Double d=numberStack.removeFirst();
Double d2=numberStack.removeFirst();
numberStack.addFirst(d2+d);
}else if(e.getObj().equals("-")) {
Double d=numberStack.removeFirst();
Double d2=numberStack.removeFirst();
numberStack.addFirst(d2-d);
}else if(e.getObj().equals("*")) {
Double d=numberStack.removeFirst();
Double d2=numberStack.removeFirst();
numberStack.addFirst(d2*d);
}else if(e.getObj().equals("/")) {
Double d=numberStack.removeFirst();
Double d2=numberStack.removeFirst();
numberStack.addFirst(d2/d);
}else if(e.getObj().equals("^")){
Double d=numberStack.removeFirst();
Double d2=numberStack.removeFirst();
numberStack.addFirst(Math.pow(d2,d));
}
}
}
return numberStack.getFirst();
}
}
另附:
import java.util.Stack;
/***
* 表达式验证
* @author LENOVO
*
*/
public class Experssion {
public int experssionVaild(String medStr) {
if(!isMatch(medStr)) {
return -2;
}
if (!(medStr.charAt(0) <= '9' && medStr.charAt(0) >= '0') && medStr.charAt(0) != '(') {
return 0;
}
if (!(medStr.charAt(medStr.length() - 1) <= '9' && medStr.charAt(medStr.length() - 1) >= '0')
&& medStr.charAt(medStr.length() - 1) != ')') {
return medStr.length() - 1;
}
for (int i = 1; i < medStr.length() - 1; i++) {
char c=medStr.charAt(i);
if (!(c <= '9' && c >= '0') && c != '('
&& c != ')' && c != '+' && c != '-'
&& c != '*' && c != '/' && c != '^'&&c != '.') {
return i;
}
if ((c == '(' && (medStr.charAt(i + 1) == '+' || medStr.charAt(i + 1) == '-'
|| medStr.charAt(i + 1) == '*' || medStr.charAt(i + 1) == '/' || medStr.charAt(i + 1) == ')'))
|| (c == '(' && (medStr.charAt(i - 1) <= '9' && medStr.charAt(i - 1) >= '0'))) {
return i;
}
if ((c == ')' && (medStr.charAt(i - 1) == '+' || medStr.charAt(i - 1) == '-'
|| medStr.charAt(i - 1) == '*' || medStr.charAt(i - 1) == '/' || medStr.charAt(i - 1) == ')'))
|| (c == ')' && (medStr.charAt(i + 1) <= '9' && medStr.charAt(i + 1) >= '0'))) {
return i;
}
if (((c == '^' && !(medStr.charAt(i - 1) <= '9' && medStr.charAt(i - 1) >= '0'))
&& (c == '^' && medStr.charAt(i - 1) != ')'))
|| ((c == '^' && !(medStr.charAt(i + 1) <= '9' && medStr.charAt(i + 1) >= '0'))
&& (c == '^' && medStr.charAt(i + 1) != '('))) {
return i;
}
if (c == '.') {
if (!(medStr.charAt(i - 1) <= '9' && medStr.charAt(i - 1) >= '0')
|| !(medStr.charAt(i + 1) <= '9' && medStr.charAt(i + 1) >= '0')) {
return i;
}
} else if ((c == '+' || c == '-' || c == '*'
|| c == '/')
&& ((medStr.charAt(i + 1) == '+' || medStr.charAt(i + 1) == '-' || medStr.charAt(i + 1) == '*'
|| medStr.charAt(i + 1) == '/' || medStr.charAt(i + 1) == '^')
|| (medStr.charAt(i - 1) == '+' || medStr.charAt(i - 1) == '-'
|| medStr.charAt(i - 1) == '*' || medStr.charAt(i - 1) == '/'
|| medStr.charAt(i - 1) == '^'))) {
return i;
}
}
return -1;
}
public boolean isMatch(String s) {
Stack<Character> sc = new Stack<Character>();
char[] c = s.toCharArray();
for (int i = 0; i < c.length; i++) {
if (c[i] == '(' || c[i] == '[' || c[i] == '{') {
sc.push(c[i]);
} else if (c[i] == ')') {
if (sc.isEmpty()) {
return false;
} else {
if (sc.peek() == '(') {
sc.pop();
}
}
} else if (c[i] == ']') {
if (sc.isEmpty()) {
return false;
} else {
if (sc.peek() == '[') {
sc.pop();
}
}
} else if (c[i] == '}') {
if (sc.isEmpty()) {
return false;
} else {
if (sc.peek() == '{') {
sc.pop();
}
}
}
}
if (sc.empty()) {
return true;
} else {
return false;
}
}
}
@Test
public void testss() {
String preStr = "5*8-9/8*2+4*6";
try {
Double d=new Count().countCore(preStr);
System.out.println(d);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
评论区
请写下您的评论...
猜你喜欢
blog
栈的应用-表达式求值
数据结构与算法
1704
表达式:ab+ab-*高级语言中采用自然语言的中缀表达式,但是计算机对中缀表达式的处理是非常困难的,而对后缀或前缀表达式则显得非常简单后缀表达式的特点: 1.在后缀表达式中,变量(操作数)出现的顺序与中
ofc
计算机系统的层次结构
official
1552
《计算机组成原理》计算机系统的层次结构计算机系统层次结构的概念,目前比较一致的计算机系统的层次结构如下图,其中左边是层次结构中各层次的名字,右边是对应于不同层的某种编程语言表现形式。计算机系统的层次
ofc
计算机硬件的基本组成
official
1012
早期冯诺依曼机早期冯诺依曼机输入设备:将信息转换成机器能够识别的形式,例如鼠标、键盘等。存储器:是计算机系统中的记忆设备,用来存放程序和数据。计算机中全部信息,包括输入的原始数据、计算机程序、中间运
ofc
计算机网络的性能指标
official
929
《计算机网络第七版谢希仁》
[TOC]一、速率 我们知道,计算机发送出的信号都是数字形式的。比特(bit)来源于binarydigit,意思是一个“二进制数字”,因此一个比特就是二进制数字中的一个
ofc
计算机网络概述
official
914
《计算机网络第七版谢希仁》
主要的名词:
ISP(InternetServiceProvider)互联网服务提供者IXP(InternetexchangePoint)互联网交换点
互联网的
ofc
计算机网络数据通讯的基础知识
official
862
包括以下两个部分:
源点(source)源点设备产生要传输的数据,例如,从计算机的键盘输入汉字,计算机产生输出的数字比特流。源点又称为源站,或信源。
发送器通常源点生成的数字比特流要通过发送器编码后
ofc
计算机网络-信道复用技术
official
1304
统计时分复用的集中器连接4个低速用户,然后将它们的数据集中起来通过高速线路发送到一个远地计算机。
统计时分复用使用STDM帧来传送复用的数据。但每一个STDM帧中的时隙数小千连接在集中器上的用户
ofc
连续分配管理方式
official
972
《操作系统》单一连续分配在单一连续分配方式中,内存被分为系统区和用户区。系统区通常位于内存的低地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据。内存中只能有一道用户程序,用户程序独
最新发表
归档
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
2024-08
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
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。