分享
 
 
 

一个用Java编写的公式解析类

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

初学Java,在工作中需要一个进行公式解析的类。从网上搜到一个相关代码,功能略有欠缺,现修改后能够实现四则运算。为了表示对网友leasion的感谢,并希望能帮助遇到同样问题人,现公开源码如下:

/**

* <p>Title: 公式解析类</p>

* <p>Description: 实现对包含“()”的表达式进行简单的四则运算。</p>

* <p>Copyright: Copyright (c) 2004</p>

* <p>Company: </p>

* @author leasion

* @version 1.0

*/

/**

* 原载于:http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=124&threadID=14861&tstart=90

* 修改者:lkz

* 修改说明:

* 1.增加对负数运算支持;

* 2.增加对公式的检查;

* 3.增加对类似公式(A+B)+(C-D)的支持。

* 4.其它一些小的改动。

*

*/

import java.util.Vector;

public class FormulaParser {

private int leftBracket = 0;//左括号个数

private int rightBracket = 0;//右括号个数

private int startL = 0;

private int startR = 0;

private double answer = 0;

private String strValue="";

private String leftNumber = "0";

private String rightNumber = "0";

public String Msg = "";

private String formula="";

private int[] sym = new int[4];

private Vector list = new Vector();

public FormulaParser(String calRule){

this.setFormula(calRule);

}

private int getLeftBracket(String calRule) {

leftBracket = 0;

startL = calRule.indexOf("(");

if (startL != -1) {

calRule = calRule.substring(startL + 1, calRule.length());

}

while (startL != -1) {

leftBracket++;

startL = calRule.indexOf("(");

calRule = calRule.substring(startL + 1, calRule.length());

}

return leftBracket;

}

private void setLeftBracket(int leftBracket) {

this.leftBracket = leftBracket;

}

public void setFormula(String calRule){

formula=replaceSubtration(calRule.trim());

formula="("+formula+")";

}

/*

/*为了使公式中支持负数,使用“`”表示减号,使用“-”表示负号

*/

private String replaceSubtration(String vstr){

String tmp="";

String result="";

int startS = vstr.indexOf("-");

if (startS !=-1) {

if (startS > 0) {

tmp = vstr.substring(startS - 1, startS);

if (!"+".equals(tmp) && !"-".equals(tmp) && !"*".equals(tmp) &&!"/".equals(tmp) &&

!"(".equals(tmp)){

result = result + vstr.substring(0, startS) + "`";

}

else

result = result + vstr.substring(0, startS + 1);

}

else

result = result + vstr.substring(0, startS + 1);

vstr = vstr.substring(startS + 1);

}

while (startS != -1) {

startS = vstr.indexOf("-");

if (startS > 0) {

tmp = vstr.substring(startS - 1, startS);

if (!"+".equals(tmp) && !"-".equals(tmp) && !"*".equals(tmp) &&!"/".equals(tmp) &&

!"(".equals(tmp))

result = result + vstr.substring(0, startS) + "`";

else

result = result + vstr.substring(0, startS + 1);

}

else

result = result + vstr.substring(0, startS + 1);

vstr = vstr.substring(startS + 1);

}

result+=vstr;

return result;

}

public String getFormula(){

return formula.replace('`','-').substring(1,formula.length()-1);

}

private int getRightBracket(String calRule) {

rightBracket = 0;

startR = calRule.indexOf(")");

if (startR != -1) {

calRule = calRule.substring(startR + 1, calRule.length());

}

while (startR != -1) {

rightBracket++;

startR = calRule.indexOf(")");

calRule = calRule.substring(startR + 1, calRule.length());

}

return rightBracket;

}

private void setRightBracket(int rightBracket) {

this.rightBracket = rightBracket;

}

/*

/*对比左右括号个数

*/

private boolean compareToLR() {

int lb = getLeftBracket(formula);

int rb = getRightBracket(formula);

boolean CTLR = false;

if (lb == rb) {

Msg = "";

CTLR = true;

} else if (lb > rb) {

Msg = "左括弧的个数多于右括弧,请检查!";

CTLR = false;

} else {

Msg = "左括弧的个数少于右括弧,请检查!";

CTLR = false;

}

return CTLR;

}

/*

/*检查公式中是否存在非法字符如(+、-)等

*/

private boolean checkFormula(){

boolean isOk=true;

String[] bracket =new String[2];

String[] sign=new String[4];

bracket[0]="(";

bracket[1]=")";

sign[0]="+";

sign[1]="`";

sign[2]="*";

sign[3]="/";

String vstr="";

for(int i=0;i<bracket.length;i++){

for(int j=0;j<sign.length;j++){

if (i==0)

vstr=bracket[i]+sign[j];

else

vstr=sign[j]+bracket[i];

if (formula.indexOf(vstr)>0){

Msg="公式中存在非法字符"+vstr;

isOk=false;

return isOk;

}

}

}

for(int i=0;i<sign.length;i++){

for(int j=0;j<sign.length;j++){

vstr=sign[i]+sign[j];

if (formula.indexOf(vstr)>0){

Msg="公式中存在非法字符"+vstr;

isOk=false;

return isOk;

}

}

}

if (formula.indexOf("()")>0){

Msg="公式中存在非法字符()";

isOk=false;

}

return isOk;

}

public boolean checkValid(){

if ((formula==null) || (formula.trim().length()<=0) ) {

Msg="请设置属性calRule!";

return false;

}

return (compareToLR()&&checkFormula());

}

/*

/*返回公式执行结果

return double

*/

public double getResult(){

String formulaStr = "", calRule = "";

double value = 0.0;

calRule = this.formula;

if (checkValid()) {

for (int i = 0; i < leftBracket; i++) {

int iStart=calRule.lastIndexOf("(") + 1;

formulaStr = calRule.substring(iStart,

iStart+calRule.substring(iStart).indexOf(")")).trim();

symbolParse(formulaStr);

value = parseString();

iStart=calRule.lastIndexOf("(");

int iEnd=calRule.substring(iStart).indexOf(")")+1;

calRule = calRule.substring(0,iStart).trim() +

value +

calRule.substring(iStart+iEnd, calRule.length()).trim();

}

}

double tmp = Math.pow(10, 10);

value = Math.round(value * tmp) / tmp;

return value;

}

public void FormulaStr(String calRule) {

String formulaStr = "";

if (checkValid()) {

for (int i = 0; i < leftBracket; i++) {

formulaStr = calRule.substring(calRule.lastIndexOf("(") + 1, calRule.indexOf(")")).trim();

symbolParse(formulaStr);

double value = parseString();

strValue=String.valueOf(value);

System.out.println("formulaStr=" + formulaStr);

//formulaVal = Double.parseDouble(formulaStr);

System.out.println("formulaVal=" + value);

calRule = calRule.substring(0, calRule.lastIndexOf("(")).trim() + value + calRule.substring(calRule.indexOf(")") + 1, calRule.length()).trim();

System.out.println("calRule=" + calRule);

}

}

}

/*

/*抽取最终括号内数据到List

*/

private void symbolParse(String str) {

list.clear();

for (int i = 0; i < 4; i++) {

compareMin(str);

while (sym[i] != -1) {

String insStr = str.substring(0, sym[i]).trim();

list.add(insStr);

insStr = str.substring(sym[i], sym[i] + 1).trim();

list.add(insStr);

str = str.substring(sym[i] + 1, str.length()).trim();

compareMin(str);

}

}

if (sym[0] == -1 && sym[1] == -1 && sym[2] == -1 & sym[3] == -1) {

list.add(str);

}

}

/*

/*循环比较赋SubString起始值

*/

private void compareMin(String str) {

int sps = str.indexOf("`");//减法subtration

sym[0] = sps;

int spa = str.indexOf("+");//加法addition

sym[1] = spa;

int spd = str.indexOf("/");//除法division

sym[2] = spd;

int spm = str.indexOf("*");//乘法multiplication

sym[3] = spm;

for (int i = 1; i < sym.length; i++) {

for (int j = 0; j < sym.length - i; j++)

if (sym[j] > sym[j + 1]) {

int temp = sym[j];

sym[j] = sym[j + 1];

sym[j + 1] = temp;

}

}

}

private double parseString()

throws NumberFormatException, StringIndexOutOfBoundsException {

try{

calculate();

return answer;

}catch(Exception e){

Msg="错误:" + e.getMessage();

return 0.0;

}

}

private void calculate() {

/*

/*处理除法

*/

int spd = list.indexOf("/");

while (spd != -1) {

leftNumber = list.get(spd - 1).toString();

rightNumber = list.get(spd + 1).toString();

list.remove(spd - 1);

list.remove(spd - 1);

list.remove(spd - 1);

double ln = Double.valueOf(leftNumber).doubleValue();

double rn = Double.valueOf(rightNumber).doubleValue();

double answer = ln / rn;

list.add(spd - 1, String.valueOf(answer));

spd = list.indexOf("/");

}

/*

/*处理乘法

*/

int spm = list.indexOf("*");

while (spm != -1) {

leftNumber = list.get(spm - 1).toString();

rightNumber = list.get(spm + 1).toString();

list.remove(spm - 1);

list.remove(spm - 1);

list.remove(spm - 1);

double ln = Double.valueOf(leftNumber).doubleValue();

double rn = Double.valueOf(rightNumber).doubleValue();

double answer = ln * rn;

list.add(spm - 1, String.valueOf(answer));

spm = list.indexOf("*");

}

/*

/*处理减法

*/

int sps = list.indexOf("`");

while (sps != -1) {

leftNumber = list.get(sps - 1).toString();

rightNumber = list.get(sps + 1).toString();

list.remove(sps - 1);

list.remove(sps - 1);

list.remove(sps - 1);

double ln = Double.valueOf(leftNumber).doubleValue();

double rn = Double.valueOf(rightNumber).doubleValue();

double answer = ln - rn;

list.add(sps - 1, String.valueOf(answer));

sps = list.indexOf("`");

}

/*

/*处理加法

*/

int spa = list.indexOf("+");

while (spa != -1) {

leftNumber = list.get(spa - 1).toString();

rightNumber = list.get(spa + 1).toString();

list.remove(spa - 1);

list.remove(spa - 1);

list.remove(spa - 1);

double ln = Double.valueOf(leftNumber).doubleValue();

double rn = Double.valueOf(rightNumber).doubleValue();

double answer = ln + rn;

list.add(spa - 1, String.valueOf(answer));

spa = list.indexOf("+");

}

if (list.size() != 0) {

String result = list.get(0).toString();

if (result == null || result.length() == 0) result = "0";

answer = Double.parseDouble(list.get(0).toString());

}

}

}

小弟初学Java,如有错误望各位网友指正。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有