|
|
|
|
继续表达式求值—支持函数 |
| 作者:佚名 来源:闪吧 作者: 该闪就闪 更新:2007-1-13 20:47:07 错误报告 我要投稿 |
这次做的和上次那个方法不同,上次是将中缀表达式转换 为后缀表达式,再利用堆栈求值,所以对函数就不知道如何做了; 而这次用的方法则完全是按人脑的计算过程,从左到右,从内至外, 函数运算也实现了,而且参数个数也没有限制,添加也很方便 目前已添加的函数有sin(),cos(),max,min(),sin和cos采用角度制 另外,这个同样也是可以使用变量的,供测试的变量有m,n,y,x, 程序中所有变量都可用,但有些是不能做算术运算的^_^
点击浏览该文件
参考(很受启发): http://www-900.ibm.com/developerWorks/cn/java/j-w3eva/index.shtml#resources
-------------------AS如下------------------ var ostr = "+,-,*,/,%,^"; var fstr = "sin,cos,max,min"; //获取运算符的优先级,非运算符的优先级为0 function isp(optr:String) { switch (optr) { case "+" : case "-" : return 1; case "*" : case "/" : case "%" : return 2; case "^" : return 3; default : return 0; } } //判断操作数的类型(数字或变量)并作相应处理 function getNum(str:String) { var ch = str.substr(0, 1); if ((ch<"0" || ch>"9") && ch != "-") { return eval(str); } else { return Number(str); } } //运算符的具体运算 function func(optr:String, va:Array) { for (var i in va) { va[i] = getNum(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 "sin" : return Math.sin(va[0]/180*Math.PI); case "cos" : return Math.cos(va[0]/180*Math.PI); case "max" : return Math.max(va[0], va[1]); case "min" : return Math.min(va[0], va[1]); } } //找出最里层的括号,并返回括号的起始位置及括号内的表达式 function godepth(estr) { var e = estr.indexOf(")"); var s = estr.lastIndexOf("(", e); estr = estr.slice(s+1, e); var obj = {s:s, e:e, estr:estr}; return obj; } //计算带括号和函数的表达式 function toNum2(estr, ostr, fstr) { var i, JHTEMP, obj = godepth(estr), hasfunc = ""; fstr = fstr.split(","); while (obj.s>=0 && obj.e>obj.s) { JHTEMP = toNum1(obj.estr, ostr); //检查左括号的外边是否是一个函数名 for (i in fstr) { if (estr.lastIndexOf(fstr[i], obj.s) == obj.s-fstr[i].length) { hasfunc = fstr[i]; break; } } if (hasfunc.length>0) { JHTEMP = func(hasfunc, JHTEMP); estr = estr.slice(0, obj.s-hasfunc.length)+JHTEMP+estr.slice(obj.e+1); hasfunc = ""; } else { JHTEMP = JHTEMP[0]; estr = estr.slice(0, obj.s)+"JHTEMP"+estr.slice(obj.e+1); } obj = godepth(estr); } estr = toNum1(estr, ostr); return estr; } //计算无括号带逗号表达式 function toNum1(estr, ostr) { var i, earray = estr.split(","); for (i in earray) { earray[i] = toNum0(earray[i], ostr); } return earray; } //计算无括号无逗号表达式 function toNum0(estr:String, ostr:String) { var i, maxisp, earray = toArray0(estr, ostr); //搜索数组,找出最高的优先级(非运算符的优先级为0) while (earray.length>1) { maxisp = 0; for (i in earray) { maxisp = Math.max(maxisp, isp(earray[i])); } //从左往右搜索优先级最高的第一个运算符并计算 for (i=0; i<earray.length; i++) { if (maxisp>0 && isp(earray[i]) == maxisp) { var va = [earray[i-1], earray[i+1]]; earray.splice(i-1, 3, func(earray[i], va)); break; } } } return getNum(earray[0]); } //分解无括号无逗号表达式字串 function toArray0(estr, ostr) { ostr = ostr.split(","); var index = [], i, temp; //搜索表达式字串中的所有运算符并记录其位置和长度 for (i in ostr) { temp = -1; while ((temp=estr.indexOf(ostr[i], temp+1)) != -1) { if (!(ostr[i] == "-" && temp == 0)) { var L = index.length; index[L] = []; index[L][0] = temp; index[L][1] = ostr[i].length; } } } function compareFunction(A, B) { return A[0]>B[0] ? 1 : A[0]<B[0] ? -1 : 0; } index.sort(compareFunction); temp = estr; var s = 0, e; estr = []; //将字串分解为元素并按顺序存储到数组里 for (i=0; i<index.length; i++) { e = index[i][0]; estr.push(temp.slice(s, e)); s = e+index[i][1]; estr.push(temp.slice(e, s)); } estr.push(temp.slice(s)); return estr; } //=============测试============ var m = 20; var n = 4; var x = 100; var y = 3; var estr = "max(2,min(3,4))-sin(30)+m*n+m/n"; var TF = new TextFormat(); TF.align = "center"; this.createTextField("hello", 1, 0, 25, 400, 20); with (hello) { type = "dynamic"; selectable = false; setNewTextFormat(TF); text = "输入表达式后按ENTER开始计算"; } this.createTextField("in_out", 2, 2, 50, 396, 20); with (in_out) { type = "input"; border = true; restrict = "A-Za-z0-9+*/%()=.,\\-\\^"; setNewTextFormat(TF); in_out.text = estr+"="+toNum2(estr, ostr, fstr); } function out() { var estr = in_out.text; var e = estr.lastIndexOf("="); if (e == -1) { e = estr.length; } estr = estr.slice(0, e); in_out.text = estr+"="+toNum2(estr, ostr, fstr); } this.onMouseUp = function() { Selection.setSelection(0, in_out.length); }; in_out.onKillFocus = out; var myListener = new Object(); Key.addListener(myListener); myListener.onKeyDown = function() { if (Key.isDown(Key.ENTER)) { out(); } }; new _jh7086();
|
|
| 文章录入:skyuu 责任编辑:skyuu |
|
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
|
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
|
|
|
|