关于字符串解析的问题

raito33 2009-07-28 01:02:04
一个文本框 让用户输入自定义算法
如(a+b)*2-5
a和b有固定的值
首先判断格式的正则我应该怎么写
还有在后台怎么解析这个字符串进行计算
或者说有什么更好的方法没?
...全文
150 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
raito33 2009-07-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhangxianwei 的回复:]
楼主可以试下,ExpressionException 随便定义一个好了
[/Quote]
相当牛b啊
谢谢了
YY_MM_DD 2009-07-28
  • 打赏
  • 举报
回复
可以使用两个栈来进行操作
一个使用放数,一个放操作符号.
数据结构书上貌似有个这样一来的算法
liulu525800 2009-07-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yanbin1016 的回复:]
呵呵 这个貌似不好弄。。。你这样让用户随便输入 你在后台解析起来应该会很麻烦吧。有括号你得先算括号里的吧。还有大括号 中括号 平方  立方 根号 等等等等。。。你都判断?不太现实吧 你不如做个计算器好了 呵呵
[/Quote]
是啊,貌似每种情况你都要判断太现实了啊!
zhangxianwei 2009-07-28
  • 打赏
  • 举报
回复
楼主可以试下,ExpressionException 随便定义一个好了
yanbin1016 2009-07-28
  • 打赏
  • 举报
回复
呵呵 这个貌似不好弄。。。你这样让用户随便输入 你在后台解析起来应该会很麻烦吧。有括号你得先算括号里的吧。还有大括号 中括号 平方 立方 根号 等等等等。。。你都判断?不太现实吧 你不如做个计算器好了 呵呵
zhangxianwei 2009-07-28
  • 打赏
  • 举报
回复
package cn.gwssi.app.common.util;

import java.util.Stack;
import java.util.regex.*;

public class Expression {
public static String OPTS = "+-*/%><][!|&=#";
public Object calculate(String expression) throws
ExpressionException {
try {
Stack Opts = new Stack();
Stack Values = new Stack();
String exp = expression + "#";
int nCount = exp.length(), nIn, nOut, nTemp;
Opts.push("#");
String temp = "", optOut = "", optIn = "", value1 = "", value2 = "",
optTemp = "", opt = "", temp1 = "";
int nFun = 0;
boolean isFun = false;
for (int i = 0; i < nCount; ) {
nTemp = 0;
opt = exp.substring(i, i + 1);
isFun = false;
temp1 = "";
while (i < nCount) {
if (!temp1.equals("")) {
if (opt.equals("(")) {
nFun++;
isFun = true;
}
else if (opt.equals(")")) {
nFun--;
}
}
if ( (nFun > 0) || ( (!isFun) && this.isValue(opt))) {
temp1 += opt;
nTemp++;
opt = exp.substring(i + nTemp, i + nTemp + 1);
}
else {
if (isFun) {
temp1 += opt;
nTemp++;
}
break;
}
}
if (temp1.equals("")) {
temp = opt;
}
else {
temp = temp1;
}
if (nTemp > 0) {
i = i + nTemp - 1;
}
temp = temp.trim();

if (this.isValue(temp)) {
temp = this.getValue(temp);
Values.push(temp);
i++;
}
else {
optIn = Opts.pop().toString();
nIn = this.getOptPriorityIn(optIn);
nOut = this.getOptPriorityOut(temp);
if (nIn == nOut) {
i++;
}
else if (nIn > nOut) {
String ret = "";
value1 = Values.pop().toString();
value2 = Values.pop().toString();
ret = String.valueOf(this.calValue(value2, optIn, value1));
Values.push(ret);
}
else if (nIn < nOut) {
Opts.push(optIn);
Opts.push(temp);
i++;
}
}
}
return Values.pop();
}
catch (ExpressionException eE) {
throw eE;
}
catch (Exception e) {
throw new ExpressionException("表达式" + expression + "格式非法!");
}
}

protected int getOptPriorityOut(String opt) throws ExpressionException {
if (opt.equals("+")) {
return 1;
}
else if (opt.equals("-")) {
return 2;
}
else if (opt.equals("*")) {
return 5;
}
else if (opt.equals("/")) {
return 6;
}
else if (opt.equals("%")) {
return 7;
}
else if (opt.equals(">")) {
return 11;
}
else if (opt.equals("<")) {
return 12;
}
else if (opt.equals("]")) {
return 13;
}
else if (opt.equals("[")) {
return 14;
}
else if (opt.equals("!")) {
return 15;
}
else if (opt.equals("|")) {
return 16;
}
else if (opt.equals("&")) {
return 23;
}
else if (opt.equals("=")) {
return 25;
}
else if (opt.equals("#")) {
return 0;
}
else if (opt.equals("(")) {
return 1000;
}
else if (opt.equals(")")) {
return -1000;
}
throw new ExpressionException("运算符" + opt + "非法!");
}

protected int getOptPriorityIn(String opt) throws ExpressionException {
if (opt.equals("+")) {
return 3;
}
else if (opt.equals("-")) {
return 4;
}
else if (opt.equals("*")) {
return 8;
}
else if (opt.equals("/")) {
return 9;
}
else if (opt.equals("%")) {
return 10;
}
else if (opt.equals(">")) {
return 17;
}
else if (opt.equals("<")) {
return 18;
}
else if (opt.equals("]")) {
return 19;
}
else if (opt.equals("[")) {
return 20;
}
else if (opt.equals("!")) {
return 21;
}
else if (opt.equals("|")) {
return 22;
}
else if (opt.equals("&")) {
return 24;
}
else if (opt.equals("=")) {
return 26;
}
else if (opt.equals("(")) {
return -1000;
}
else if (opt.equals(")")) {
return 1000;
}
else if (opt.equals("#")) {
return 0;
}
throw new ExpressionException("运算符" + opt + "非法!");
}

protected String getOPTS() {
return OPTS;
}

protected boolean isValue(String cValue) {
String notValue = this.getOPTS() + "()";
return notValue.indexOf(cValue) == -1;
}

protected boolean isOpt(String value) {
return this.getOPTS().indexOf(value) >= 0;
}

protected double calValue(String value1, String opt, String value2) throws
ExpressionException {
try {
double dbValue1 = Double.valueOf(value1).doubleValue();
double dbValue2 = Double.valueOf(value2).doubleValue();
long lg = 0;
if (opt.equals("+")) {
return dbValue1 + dbValue2;
}
else if (opt.equals("-")) {
return dbValue1 - dbValue2;
}
else if (opt.equals("*")) {
return dbValue1 * dbValue2;
}
else if (opt.equals("/")) {
return dbValue1 / dbValue2;
}
else if (opt.equals("%")) {
lg = (long) (dbValue1 / dbValue2);
return dbValue1 - lg * dbValue2;
}
else if (opt.equals(">")) {
if (dbValue1 > dbValue2)
return 1;
else
return 0;
}
else if (opt.equals("<")) {
if (dbValue1 < dbValue2)
return 1;
else
return 0;
}
else if (opt.equals("]")) {
if (dbValue1 >= dbValue2)
return 1;
else
return 0;
}
else if (opt.equals("[")) {
if (dbValue1 <= dbValue2)
return 1;
else
return 0;
}
else if (opt.equals("!")) {
if (dbValue1 != dbValue2)
return 1;
else
return 0;
}
else if (opt.equals("|")) {
if (dbValue1 > 0 || dbValue2 > 0)
return 1;
else
return 0;
}
else if (opt.equals("&")) {
if (dbValue1 > 0 && dbValue2 > 0)
return 1;
else
return 0;
}
else if (opt.equals("=")) {
if (dbValue1 == dbValue2)
return 1;
else
return 0;
}
}
catch (Exception e) {
throw new ExpressionException("值" + value1 + "或" + value2 + "在进行" + opt +
"运算时非法!");
}
throw new ExpressionException("运算符" + opt + "非法!");
}

protected String getValue(String oldValue) throws ExpressionException {
String reg = "^([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_.()]+)\\)$";
if (this.isFunctionCal(oldValue)) {
Pattern p = Pattern.compile(reg);
Matcher m = p.matcher(oldValue);
m.find();
return calFunction(m.group(1), m.group(2));
}
return oldValue;
}

protected boolean isFunctionCal(String value) {
String reg = "^([a-zA-Z0-9_]+)\\(([a-zA-Z0-9_.()]+)\\)$";
return value.matches(reg);
}

protected String calFunction(String function, String value) throws
ExpressionException {
String lowerFun = function.toLowerCase();
double db = 0;
try {
db = Double.valueOf(this.getValue(value)).doubleValue();
if (lowerFun.equals("log")) {
return String.valueOf(Math.log(db));
}
else if (lowerFun.equals("square")) {
return String.valueOf(Math.pow(db, 2));
}
else if (lowerFun.equals("sqrt")) {
return String.valueOf(Math.sqrt(db));
}
else if (lowerFun.equals("sin")) {
return String.valueOf(Math.sin(db));
}
else if (lowerFun.equals("asin")) {
return String.valueOf(Math.asin(db));
}
else if (lowerFun.equals("cos")) {
return String.valueOf(Math.cos(db));
}
else if (lowerFun.equals("tan")) {
return String.valueOf(Math.tan(db));
}
else if (lowerFun.equals("atan")) {
return String.valueOf(Math.atan(db));
}
else if (lowerFun.equals("ceil")) {
return String.valueOf(Math.ceil(db));
}
else if (lowerFun.equals("exp")) {
return String.valueOf(Math.exp(db));
}
}
catch (Exception e) {
throw new ExpressionException("函数" + function + "值" + value + "非法!");
}

throw new ExpressionException("函数" + function + "不支持!");
}

public static void main(String[] args) throws ExpressionException {
Expression be = new Expression();
// String exp = "(sin(ceil(sqrt(100)))*29+20+30*3+0|0|1+1&1*5+2)<2";
String exp = "(20-100)<1000";
System.out.println(be.calculate(exp));
}
}

APOLLO_TS 2009-07-28
  • 打赏
  • 举报
回复
又是计算器。
wunaiyafan 2009-07-28
  • 打赏
  • 举报
回复
我倒!
fyjava1984 2009-07-28
  • 打赏
  • 举报
回复
顶顶顶
raito33 2009-07-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yanbin1016 的回复:]
你的意思是 整个表达式都是用户自己写的是吗?比如:(a+b)*2-5 或 a*(2+b)/5 之类的?
[/Quote]
是的
yanbin1016 2009-07-28
  • 打赏
  • 举报
回复
你的意思是 整个表达式都是用户自己写的是吗?比如:(a+b)*2-5 或 a*(2+b)/5 之类的?
yanbin1016 2009-07-28
  • 打赏
  • 举报
回复
先占个沙发

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧