package com.fbj.expression;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import com.fbj.expression.parse.Parse;
import com.fbj.expression.token.NumToken;
import com.fbj.expression.token.OprToken;
import com.fbj.expression.token.Token;
import com.fbj.expression.util.Util;
public class Expression {
public static List<Token> parse(String src){
if(src != null && !src.isEmpty()){
src = src.replaceAll(" +", "").replaceAll("÷", "/").replaceAll("×", "/");
int mark = 0;
Token token = null;
List<Token> tokens = new ArrayList<Token>();
while (mark < src.length()) {
Parse parse = Util.getParse(String.valueOf(src.charAt(mark)));
token = parse.parse(src, mark);
if(token != null){
tokens.add(token);
mark = token.getEnd();
}else {
mark++;
}
}
return tokens;
}
return null;
}
public static Token run(List<Token> tokens){
if(tokens != null){
//checkMinus(tokens);
int mark = 0;
int weight = 0;
int weightOffset = 0;
run : while (tokens.size() >= 2) {
weightOffset = 0;
weight = 0;
// if(tokens.size() == 5){
// System.out.println();
// }
System.out.print("要处理的表达式exp=");
for(Token token2 : tokens){
System.out.print("[" +token2.getValue() + "]");
}
System.out.println();
// System.out.println("还剩:" + tokens.size());
//int i = 0;
//按优先级查找
Token token =null;
for(int i =0 ; i <tokens.size() ; i++){
token = tokens.get(i);
if(token.getWeight() > weight){
weight = token.getWeight();
weightOffset = i;
}
if(weight == Util.weights.length -1){
}
}
//System.out.println("最优先:" + tokens.get(weightOffset).getValue());
if(weight > 2){
//不是基础运算,继续化简
//首先找到他的配对标记
int flag = 0;
int end = 0;
Token subToken = null;
token = tokens.get(weightOffset);
for(int j = weightOffset+1 ; j < tokens.size(); j++){
subToken = tokens.get(j);
//System.out.println(subToken.getValue());
if(subToken.getWeight() == weight){
//找到同优先级的,判断是否是一对
if(subToken.getValue().equals(token.getValue())){
flag++;
}else if(subToken.getValue().equals(Util.getEnd(token.getValue()))){
flag--;
}
if(flag == -1){
//找到了
end = j;
break;
}
}
}
if(end > 0){
//先算出结果
List<Token> subRTokens = tokens.subList(weightOffset + 1, end);
Token subResultToken = run(subRTokens);
//tokens.removeAll(subRTokens);
// System.out.print("\n旧reg=");
// for(Token token2 : tokens){
// System.out.print(token2.getValue());
// }
tokens.remove(weightOffset +2);
tokens.remove(weightOffset);
weight = 0;
}
continue run;
}
// System.out.print("\nexp=");
// for(Token token2 : tokens){
// System.out.print( token2.getValue());
// }
// System.out.println();
//找完优先级开始运算
Token result = null;
if(tokens.size() >=3 && weightOffset != 0){
result = calculation(tokens.get(weightOffset - 1), tokens.get(weightOffset + 1), tokens.get(weightOffset));
tokens.remove(weightOffset -1);
tokens.remove(weightOffset -1);
tokens.remove(weightOffset -1);
tokens.add(weightOffset -1, result);
}else {
result = calculation(null, tokens.get(weightOffset + 1), tokens.get(weightOffset));
tokens.remove(0);
tokens.remove(0);
tokens.add(0 , result);
}
}
return tokens.get(0);
}
return null;
}
public static Token calculation(Token pre , Token next , Token opr){
if(next instanceof NumToken && opr instanceof OprToken){
if(pre == null){
if ("-".equals(opr.getValue())) {
next.setValue("-" +next.getValue());
}
return next;
}else if (next instanceof NumToken ){
String op = opr.getValue();
if(pre.getC().equals(Double.class) || next.getC().equals(Double.class) || "/".equals(opr.getValue())){
BigDecimal bigDecimal = new BigDecimal(pre.getValue());
BigDecimal bigDecimal2 = new BigDecimal(next.getValue());
BigDecimal result = null;
if("+".equals(op)){
result = bigDecimal.add(bigDecimal2);
}else if ("-".equals(op)) {
result = bigDecimal.subtract(bigDecimal2);
}else if ("*".equals(op)) {
result = bigDecimal.multiply(bigDecimal2);
}else if ("/".equals(op)) {
result = bigDecimal.divide(bigDecimal2 , 9 , BigDecimal.ROUND_CEILING);
}
Token token = new NumToken();
token.setC(Double.class);
token.setValue(result.toString().replaceAll("0+$", ""));
return token;
}else {
Integer integer1 = new Integer(pre.getValue());
Integer integer2 = new Integer(next.getValue());
Integer result = null;
if("+".equals(op)){
result = integer1 + integer2;
}else if ("-".equals(op)) {
result = integer1 - integer2;
}else if ("*".equals(op)) {
result = integer1 * integer2;
}else if ("/".equals(op)) {
result = integer1 / integer2;
}
Token token = new NumToken();
token.setC(Integer.class);
token.setValue(result.toString());
return token;
}
}
}
return null;
}
public static Token start(String exp){
List<Token> tokens = Expression.parse(exp);
return run(tokens);
}
public static void main(String[] args) {
String exp = "-(10 * 2) +(-9*45.8)/4*3-2";
//List<Token> tokens = Expression.parse(exp);
// for(Token token : tokens)
// System.out.println(token.getValue() + "," + token.getWeight());
Token token = start(exp);
System.out.println("\n" +exp + "="+token.getValue());
}
public static void checkMinus(List<Token> tokens){
Token pre = null;
Token c = null;
for(int i = 0 ; i < tokens.size() ; i++){
c = tokens.get(i);
if("-".equals(c.getValue())){
if(pre == null || pre instanceof OprToken){
if((i+1 < tokens.size())){
Token next = tokens.get(i+1);
if(next instanceof NumToken){
next.setValue("-" + next.getValue());
tokens.remove(i);
}
}
}
}
pre = c;
}
}
public static void print(String title , List<Token> tokens){
System.out.print("\n"+title+"表达式");
for(Token token : tokens){
System.out.print(token.getValue());
}
System.out.println();
}
}
package com.fbj.expression.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.Templates;
import com.fbj.expression.parse.NumParse;
import com.fbj.expression.parse.OprParse;
import com.fbj.expression.parse.Parse;
import com.fbj.expression.parse.StopParse;
import com.fbj.expression.token.Token;
public class Util {
public final static String stopReg = "[\\(\\)\\[\\]\\{\\}]";//停止符号
public final static String stopString = "}])";//停止符号
public final static String oprReg = "[\\+\\-\\*/]";//运算符号
public final static String numReg = "\\d";//数值符号
public final static String weights[] = new String[]{"num" , "opr" , "" , "stop"};
private static List<String> regs;
private static Map<String, Parse> parses;
private static Map<String, String> stops;
static{
regs = new ArrayList<String>();
regs.add(stopReg);
regs.add(oprReg);
regs.add(numReg);
parses = new HashMap<String, Parse>();
parses.put(stopReg, new StopParse());
parses.put(oprReg, new OprParse());
parses.put(numReg, new NumParse());
stops = new HashMap<String, String>();
stops.put("{" , "}");
stops.put("[" , "]");
stops.put("(", ")");
}
public static List<String> getRegs(){
return regs;
}
public static Parse getParse(String input) {
if(input == null)
return null;
for (int i = 0; i < 3; i++) {
if(input.matches(regs.get(i))){
return parses.get(regs.get(i));
}
}
return null;
}
/**
* 获取原算法的优先级
* @return
*/
public static int getWeight(String type , String value){
if(type == null)
return -1;
//System.out.println(weights[i]);
if("stop".equals(type)){
int w = stopString.indexOf(value);
if(w == -1){
w = stopString.indexOf(stops.get(value));
}
return 3 + w;
}else if("opr".equals(type)) {
if("*".equals(value) || "/".equals(value)){
return 2;
}else {
return 1;
}
}else {
return 0;
}
}
public static void main(String[] args) {
System.out.println(parses.get(regs.get(2)));
}
public static String getEnd(String start) {
return stops.get(start);
}
}
分享到:
相关推荐
标题中的“四则运算表达式解析器源码(C#)”是指一个使用C#编程语言编写的程序,它的主要功能是解析包含加法(+)、减法(-)、乘法(*)、除法(/)、取模(%)以及比较运算符(<、>、=、、、>=)的数学表达式。...
在编写代码时我们有时候会碰到需要自己解析四则运算表达式的情况,本文简单的介绍使用JavaScript实现对简单四则运算表达式的解析。 一、熟悉概念 中缀表示法(或中缀记法)是一个通用的算术或逻辑公式表示方法, ...
工具提供四则运算解析功能。将.hpp文件引入C++工程中即可使用。详情用法参见文件中注释
对于四则运算,这通常涉及到解析表达式的顺序,如先乘除后加减,以及处理括号内的优先级。这个阶段可能使用上下文无关文法(Context-Free Grammar, CFG)来描述语言的结构,并应用如LL(1)或LR(1)等解析技术。 3. **...
例: Expression e = new [removed]"1+2*((3+5)/10*5*4 +(1-2)/4)"); System.out.println(e.eval());//32.5 要求jdk1.6
这种表示法在计算机科学中广泛应用于算法设计和计算器实现,特别是对于解析和执行四则运算。本项目是一个基于JavaScript开发的逆波兰表达式解析库,用于实现四则运算的计算器。 在逆波兰表达式中,一个表达式如 "2 ...
四则运算解析器是一种计算机程序,它能够接收包含加、减、乘、除等四则运算符的字符串表达式,并将其转化为可执行的计算过程。这个解析器通常用于解决基础的数学问题,对于编程初学者来说,理解并实现这样一个解析器...
在解析四则运算表达式时,我们通常采用逆波兰表示法(Reverse Polish Notation,RPN),也称为后缀表达式。这种表示法不需要括号,运算符放在操作数之后,使得计算过程更为直观。例如,表达式 "2 + 3 * 4" 在后缀...
《Delphi7字符串四则运算解析》 在编程领域,Delphi7是一款经典的面向对象的集成开发环境(IDE),尤其适合开发Windows桌面应用程序。本文将深入探讨如何在Delphi7中实现字符串四则运算,这对于那些需要处理动态...
首先,让我们详细解析四则运算的含义: 1. 加法(+):加法是最基本的运算,表示将两个或多个数值相加得到一个新的总和。例如,3 + 4 = 7。 2. 减法(-):减法是求一个数从另一个数中减去多少得到的结果。例如,7...
### 栈的四则运算实现及详解 #### 一、引言 在计算机科学中,栈是一种非常重要的数据结构,其遵循后进先出(LIFO, Last In First Out)的原则...这种方法利用了栈的数据结构特性,使得四则运算的解析变得简单且高效。
解析expression四则运算表达式 如:(1+2*3.5*(2+3)-10+18*20)
四则运算包括加法(+)、减法(-)、乘法(*)和除法(/)。混合运算意味着计算器不仅支持单个操作,还能处理带有括号的复杂表达式,按照运算符优先级正确计算结果。实现这样的计算器,我们需要理解Qt的信号和槽机制...
"java实现字符串四则运算公式解析工具类的方法" 今天小编将为大家分享java实现字符串四则运算公式解析工具类的方法,这个工具类能够帮助用户快速解析和计算字符串形式的四则运算公式。这个工具类被命名为...
自己写的解析形如 "1*2*3+45+54/6" 的四则运算表达式,目前是第一个版本 不支持负数参与计算 如有负数 请自行转换 后续版本 增加对负数运算的支持和()[]{}等符号的支持 最终版将支持 协议插件 如有bug 请联系 ...
在本项目“C语言数据结构用栈实现四则运算”中,开发者利用栈这种数据结构来处理数学中的四则运算,包括加法(+)、减法(-)、乘法(*)和除法(/)。这种方法相比传统的递归或循环方式,通常更加简洁且易于理解。...
利用堆栈实现的简单四则运算 本文主要介绍如何使用 MFC 应用程序创建一个简单的四则运算表达式计算器,通过设置项目类型、添加控件变量、事件处理函数等步骤,实现了基本的四则运算功能。 MFC 应用程序简介 MFC...
在C#中实现四则运算是一项基础但至关重要的任务,这通常涉及到解析用户输入的字符串形式的运算式子,并进行计算。在本教程中,我们将深入探讨如何在C#中处理四则运算,包括加法、减法、乘法和除法。 首先,我们需要...