//用例:
//estr="sum(1,2,3,sin((4+5)*10),acos(cos(70)),avg(1,2,3,4,5,6,7,8,9))+2e+4";
//Expression.evaluate(estr);
/**
* @author jh7086
*/
class Expression {
//为方便检测"+ -"是否为正负号,限用单个字符的运算符
private static var ostr : String = "+,-,*,/,%,^,e";
private static var oarr : Array = ostr.split(",");
private static var fstr : String = "abs,round,sqrt,sin,cos,tan,acos,asin,atan,log,exp,sum,avg,count,max,min";
private static var farr : Array = fstr.split(",");
//
public static function evaluate(estr : String) : String {
trace(estr);
return reckon2(estr).toString();
}
public static function listOperators() : String {
return ostr;
}
public static function listFunctions() : String {
return fstr;
}
//运算符及函数的具体运算
private static function func(optr : String, va : Array) : Number {
var i : Number;
if (typeof (va[0]) == "object") {
for (i in va[0]) {
va[i] = _Number(va[0][i]);
}
} else {
for (i in va) {
va[i] = _Number(va[i]);
}
}
switch (optr) {
case "+" :
return va[0] + va[1];
case "-" :
return va[0] - va[1];
case "*" :
return va[0] * va[1];
case "/" :
return va[0] / va[1];
case "%" :
return va[0] % va[1];
case "^" :
return Math.pow(va[0], va[1]);
case "e" :
return va[0] * Math.pow(10, va[1]);
case "abs" :
return Math.abs(va[0]);
case "round" :
return Math.round(va[0]);
case "sqrt" :
return Math.sqrt(va[0]);
case "sin" :
return Math.sin(va[0] / 180 * Math.PI);
case "cos" :
return Math.cos(va[0] / 180 * Math.PI);
case "tan" :
return Math.tan(va[0] / 180 * Math.PI);
case "acos" :
return Math.acos(va[0]) * 180 / Math.PI;
case "asin" :
return Math.asin(va[0]) * 180 / Math.PI;
case "atan" :
return Math.atan(va[0]) * 180 / Math.PI;
case "log" :
return Math.log(va[0]);
case "exp" :
return Math.exp(va[0]);
case "sum" :
return sum(va);
case "avg" :
return sum(va) / va.length;
case "count" :
return va.length;
case "max" :
return max(va);
case "min" :
return min(va);
}
}
//获取运算符的优先级,非运算符的优先级为0
private static function isp(optr : String) : Number {
switch (optr) {
case "+" :
case "-" :
return 1;
case "*" :
case "/" :
case "%" :
return 2;
case "^" :
return 3;
case "e" :
return 4;
default :
return 0;
}
}
//求和函数
private static function sum(mydata : Array) : Number {
var s : Number = 0;
for (var i in mydata) {
s += mydata[i];
}
return s;
}
//求最小值
private static function min(mydata : Array) : Number {
var s : Number = mydata[0];
for (var i in mydata) {
if (mydata[i] < s) {
s = mydata[i];
}
}
return s;
}
//求最大值
private static function max(mydata : Array) : Number {
var s : Number = mydata[0];
for (var i in mydata) {
if (mydata[i] > s) {
s = mydata[i];
}
}
return s;
}
//判断操作数的类型(数字或变量)并作相应处理
private static function _Number(str : String) : Number {
if (str == "") {
return 0;
}
var ch : String = str.substr(0, 1);
if ((ch < "0" || ch > "9") && ch != "+" && ch != "-") {
return eval(str);
} else {
return Number(str);
}
}
//找出最里层的括号,并返回括号的起始位置及括号内的表达式
private static function getInner(estr : String) : Object {
var e : Number = estr.indexOf(")");
var s : Number = estr.lastIndexOf("(", e);
estr = estr.slice(s + 1, e);
if (e != -1) {
var obj : Object = {s:s, e:e, estr:estr};
return obj;
} else {
return null;
}
}
//计算带括号和函数的表达式
private static function reckon2(estr : String) : Array {
var i : Number, JHTEMP : Array, obj : Object, funcStr : String;
obj = getInner(estr);
while (obj != null) {
JHTEMP = reckon1(obj.estr);
//检查左括号的外边是否是一个函数名
funcStr = null;
for (i in farr) {
var fIndex : Number = estr.lastIndexOf(farr[i], obj.s);
if (fIndex != -1 && fIndex == obj.s - farr[i].length) {
funcStr = farr[i];
break;
}
}
if (funcStr != null) {
JHTEMP[0] = func(funcStr, JHTEMP);
//JHTEMP[0] = Math.round(Number(JHTEMP[0])*10000000)/10000000;//取消可能出现的科学计数法,如1.5e-7
estr = estr.slice(0, obj.s - funcStr.length) + JHTEMP[0] + estr.slice(obj.e + 1);
} else {
//JHTEMP[0] = Math.round(Number(JHTEMP[0])*10000000)/10000000;
estr = estr.slice(0, obj.s) + JHTEMP[0] + estr.slice(obj.e + 1);
}
trace(estr);
obj = getInner(estr);
}
var eArr : Array = reckon1(estr);
return eArr;
}
//计算无括号带逗号表达式 9,1+1,7*2
private static function reckon1(estr : String) : Array {
var i : Number, eArr : Array = estr.split(",");
for (i in eArr) {
eArr[i] = reckon0(eArr[i]);
}
return eArr;
}
//计算无括号无逗号表达式 1+1/2
private static function reckon0(estr : String) : Number {
var i : Number, maxisp : Number, eArr : Array = toArray0(estr);
//搜索数组,找出最高的优先级(非运算符的优先级为0)
while (eArr.length > 1) {
maxisp = 0;
for (i in eArr) {
maxisp = Math.max(maxisp, isp(eArr[i]));
}
//从左往右搜索优先级最高的第一个运算符并计算
for (i = 0;i < eArr.length; i++) {
if (maxisp > 0 && isp(eArr[i]) == maxisp) {
var va : Array = [eArr[i - 1], eArr[i + 1]];
eArr.splice(i - 1, 3, func(eArr[i], va));
break;
}
}
}
return _Number(eArr[0]);
}
//分解无括号无逗号表达式字串
private static function toArray0(estr : String) : Array {
var index : Array = [], i : Number, temp : Number;
//将正负号变为加减号
if (estr.substr(0, 1) == "-" || estr.substr(0, 1) == "+") {
estr = "0" + estr;
}
//搜索表达式字串中的所有运算符并记录其位置和长度
for (i in oarr) {
temp = -1;
while ((temp = estr.indexOf(oarr[i], temp + 1)) != -1) {
//如果不是"+-"或者"+-"的前一个字符不属于运算符
if (oarr[i] != "+" && oarr[i] != "-" || temp != 0 && ostr.indexOf(estr.substr(temp - 1, 1)) == -1) {
index.push([temp, oarr[i].length]);
//否则表示当前检测到的是"+-",且代表的是正负号
}
}
}
index.sort(compareFunction);
var _temp : String = estr;
var s : Number = 0, e : Number;
var eArr : Array = [];
//将字串分解为元素并按顺序存储到数组里
for (i = 0;i < index.length; i++) {
e = index[i][0];
eArr.push(_temp.slice(s, e));
s = e + index[i][1];
eArr.push(_temp.slice(e, s));
}
eArr.push(_temp.slice(s));
return eArr;
}
private static function compareFunction(A, B) : Number {
return A[0] > B[0] ? 1 : A[0] < B[0] ? -1 : 0;
}
}