/**
?* <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();
????? }
??? }
??? System.out.println(Msg);
??? 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());
??????? }
??? }
}
原文引自:http://blog.csdn.net/lkz912/archive/2004/12/31/236267.aspx