Fdream's Blog
专注于WEB前端开发
Powered by Google

计算字符串表达式的函数(AS版)

3 雨天 2006-6
Fdream 发表于 Flash, 已被阅读 23827 次, 评论 5 条
关键词:AS ActionScript 源代码
[ 阅读字体大小: ]

先废话几句:AS中的计算误差也真是很有趣,例如:6.4-6.3=0.100000000000001,这是在Flash 8中运行的结果,我真是无语了!附图一张:

evalString 函数介绍:

evalString(expression:String) : Number

expression 为一个算术表达式,该函数将计算此表达式的值,并返回计算结果。此表达式仅限于简单的+、-、×、÷以及带括号的运算,表达式中不得有其他符号,包括空格。表达式中的数字不仅限于一位整数,也可为多位整数,甚至是小数

参数

expression:String - 一个字符串表达式。

返回

Number - 一个数值。

示例

var infix:String = "(48-20*(6.2-5))/(18-15)";

trace(evalString(infix)); //output 8

函数算法思想

算法思想和上一篇《把中缀表达式转化为后缀表达式》中所表述的思想基本一致,只是在扫描数据以及运算符退栈时处理方法不同。

在扫描字符串时,若是数字,则加到一个字符串后面,同时扫描下一个字符,若不是数字字符也不是小数点,则把当前字符串转换为数字压入数字栈。

在遇到运算符需要退栈时,从数字栈中取出栈顶的两个数字,和退栈运算符一起进行运算,并把计算结果压入数字栈中,依次循环,直到无须退栈。扫描完成后,退栈运算符,并依次和数字栈中栈顶的数字进行运算,直至运算符栈为空。

函数代码如下:

引用内容:

/********************************************/

/* Calculate the value of a string */

/* Example: */

/* var infix:String = "(12.2-6.2)/(8-5)"; */

/* trace(evalString(infix)); //output 2 */

/********************************************/

/* Please keep this info when you quote */

/* www.afdream.com */

/* Author:Fdream */

/* Fdream All Rights Reserved */

/********************************************/

function evalString(infix:String) {

var opArray:Array = new Array();

//栈底标记

opArray[0] = '@';

var op:Number = 1;

var postfix:Array = new Array();

var post:Number = 0;

//保存计算结果

var res:Number = 0;

var i, j;

var tempString:String = new String();

//计算两个数

function Caculate(opSign:String) {

if (opSign == '+') {

res = postfix[post-2]+postfix[post-1];

} else if (opSign == '-') {

res = postfix[post-2]-postfix[post-1];

} else if (opSign == '*') {

res = postfix[post-2]*postfix[post-1];

} else if (opSign == '/') {

if (!postfix[post-1]) {

trace("Expression Error!");

} else {

res = postfix[post-2]/postfix[post-1];

}

}

postfix[post-1] = 0;

postfix[post-2] = res;

post--;

}

//扫描中缀表达式

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

switch (infix.charAt(i)) {

//左括号就直接入栈

case '(' :

opArray[op] = infix.charAt(i);

op++;

break;

//右括号则退栈计算,直到遇见一个左括号

case ')' :

for (j=op-1; j>0; j--) {

if (opArray[j] != '(') {

Caculate(opArray[j]);

opArray[j] = '#';

} else {

opArray[j] = '#';

break;

}

}

op = j;

break;

case '*' :

case '/' :

//如果栈顶的运算符为*或/,则先退栈,再入栈,否则直接入栈

if (opArray[op-1] == '*') {

op--;

Caculate(opArray[op]);

opArray[op] = '#';

} else if (opArray[op-1] == '/') {

op--;

Caculate(opArray[op]);

opArray[op] = '#';

}

opArray[op] = infix.charAt(i);

op++;

break;

case '+' :

case '-' :

//如果栈顶的运算符不是左括号也不是栈底,则先退栈计算,再入栈

if (opArray[op-1] != '(' && opArray[op-1] != '@') {

op--;

Caculate(opArray[op]);

opArray[op] = '#';

}

opArray[op] = infix.charAt(i);

op++;

break;

default :

//如果是数字字符或者小数点则转化为数字存入数组

//如果下一个字符是运算符则把当前数字存入数组

tempString += infix.charAt(i);

var temp:String = new String();

temp = infix.charAt(i+1);

if (temp != '.' && (temp>'9' || temp<'0')) {

postfix[post] = parseFloat(tempString);

post++;

tempString = "";

}

//trace(postfix);

}

}

//扫描完成,全部退栈

for (j=op-1; j>0; j--) {

if (opArray[j] != '@') {

Caculate(opArray[j]);

opArray[j] = '#';

} else {

break;

}

}

//返回结果

return postfix[0];

}

Related articles 您可能对这些文章也感兴趣:
Related comments 与该文相关的评论:(我也想说几句)
引用这个评论  zszen 于 3/5/2007 4:44:25 PM 发表评论: 

我认为可以把大家经常用到的Math也给解释了,比如Math就不输入了,直接"sqrt(2)"就是对2开方 这样能支持更多运算

我认为可以把大家经常用到的Math也给解释了,比如Math就不输入了,直接"sqrt(2)"就是对2开方 这样能支持更多运算
引用这个评论  jencce 于 6/7/2006 11:33:42 PM 发表评论: 

那个是计算机的浮点数运算的问题吧

2进制表示10进制会有误差的噢

不修正就会这样的

那个是计算机的浮点数运算的问题吧 2进制表示10进制会有误差的噢 不修正就会这样的
引用这个评论  flu 于 6/4/2006 5:51:19 PM 发表评论: 

回去研究一哈.[smile][smile]

回去研究一哈.[smile][smile]
引用这个评论  Fdream 于 6/4/2006 5:03:54 PM 发表评论: 

没必要看懂啦,直接拿去用就好了,嘿嘿

没必要看懂啦,直接拿去用就好了,嘿嘿
引用这个评论  一剑 于 6/4/2006 1:02:58 PM 发表评论: 

眼睛都看花咯还是看不懂

眼睛都看花咯还是看不懂
Add a comment 我来说两句: 
禁止表情
禁止UBB
禁止图片
识别链接
识别关键字
表  情
arrow
用户名:   密码:  (匿名可不写) 同时注册?
验证码:   看不清?换个图片  看不清楚?换个图片

 
Copyright © 2005-2008,Fdream All Rights Reserved
Processed in 0.2031276 second(s) , unknow queries
Powered by OWord V0.1, Even Not Alpha
(此博客程序为半成品,请勿索取,以免给您的心灵造成创伤^_^)
鄂ICP备05026031号