2004/12/17 | 表达式求值——中缀
类别(Flash习作) | 评论(1) | 阅读(876) | 发表于 12:03

说明:可使用变量(里面有个kk=20供测试),目前不能使用函数,单目运算等
复制以下代码到首帧:
-----------------------------------------------------
//运算符的定义:txt-运算符符号;isp-运算符优先级
function setupOptrs() {
  var optrs = "=.+.-.*./.%.^.(.).,";
  optrs = optrs.split(".");
  for (var i in optrs) {
    var temp = optrs[i];
    optrs[i] = {};
    optrs[i].txt = temp;
    switch (temp) {
    case "^" :
      optrs[i].isp = 3;
      break;
    case "*" :
    case "/" :
    case "%" :
      optrs[i].isp = 2;
      break;
    case "+" :
    case "-" :
      optrs[i].isp = 1;
      break;
    default :
      optrs[i].isp = 0;
      break;
    }
  }
  return optrs;
}
//运算符的具体运算
function _optrs(pp, p1, p2) {
  switch (pp) {
  case "+" :
    return p1+p2;
  case "-" :
    return p1-p2;
  case "*" :
    return p1*p2;
  case "/" :
    return p1/p2;
  case "%" :
    return p1%p2;
  case "^" :
    return Math.pow(p1, p2);
  }
}
//排序(运算符出现的先后顺序)时使用的比较函数
function compareFunction(A:Object, B:Object) {
  return A.ind<B.ind ? -1 : A.ind>B.ind ? 1 : 0;
}
//建立中缀表达式:分离出表达式字串中的元素,按顺序存入数组,并标记其类型:typ>=0:运算符;typ=-1:数字常量;typ=-2:变量(变量名不能以数字开头,而且不能包含运算符)
function setupIFX(txt:String, optrs:Array) {
  //将表达式标准化:截取"="之前的部分,在前面添"(",后面添")=";然后,如果"-"左端为"("或",",则在"-"左端添加"0"将负号变为减号
  var startIndex = -1;
  if ((startIndex=txt.indexOf("=", startIndex+1)) != -1){
    txt=txt.slice(0, startIndex);
  }
  txt = "("+txt+")=";
  var startIndex = -1;
  while ((startIndex=txt.indexOf("-", startIndex+1)) != -1) {
    var ch = txt.substr(startIndex-1, 1);
    if (ch == "(" || ch == ",") {
      txt = txt.slice(0, startIndex)+"0"+txt.slice(startIndex);
    }
  }
  //-----标准化完成-------
  //取得所有运算符在表达式字串中的位置
  var a = [];
  for (var i in optrs) {
    var s = optrs[i].txt;
    var startIndex = -1;
    while ((startIndex=txt.indexOf(s, startIndex+1)) != -1) {
      //a.push(startIndex);
      var L = a.length;
      a[L] = {};
      a[L].optrNum = i;
      a[L].len = s.length;
      a[L].ind = startIndex;
    }
  }
  a.sort(compareFunction);
  //将字串转换为数组
  var exp = [];
  for (var i = 0; i<a.length; i++) {
    var L = exp.length;
    exp[L] = {};
    exp[L].txt = optrs[a[i].optrNum].txt;
    //typ表示类型:typ>=0:运算符;typ=-1:数字常量;typ=-2:变量(变量名不能以数字开头,而且不能包含运算符)
    exp[L].typ = a[i].optrNum;
    var str = txt.substring(a[i].ind+a[i].len, a[i+1].ind);
    if (str != "") {
      var L = exp.length;
      exp[L] = {};
      exp[L].txt = str;
      str = str.substr(0, 1);
      exp[L].typ = (str>="0" && str<="9") ? -1 : -2;
    }
  }
  return exp;
}
//中缀表达式转为后缀表达式
function ifxToPFX(ifx:Array, optrs:Array) {
  var pfx = [], s = [];
  for (var i = 0; i<ifx.length; i++) {
    //typ<0表示当前元素是"操作数",直接送入pfx
    if (ifx[i].typ<0) {
      pfx.push(ifx[i]);
      //typ>=0表示当前元素是"运算符"
    } else if (ifx[i].txt == "(") {
      s.push(ifx[i]);
    } else if (ifx[i].txt == ")") {
      while (true) {
        var temp = s.pop();
        if (temp.txt == "(") {
          break;
        }
        pfx.push(temp);
      }
      //遇到表达式结束符"="
    } else if (ifx[i].txt == "=") {
      while (s.length>1) {
        pfx.push(s.pop());
      }
      //s栈为空OR当前>s栈顶
    } else if (optrs[ifx[i].typ].isp>optrs[s[s.length-1].typ].isp || s.length == 0) {
      s.push(ifx[i]);
    } else {
      //当前<=s栈顶
      while (optrs[ifx[i].typ].isp<=optrs[s[s.length-1].typ].isp) {
        pfx.push(s.pop());
      }
      s.push(ifx[i]);
    }
  }
  return pfx;
}
//后缀表达式求值
function pfxToNUM(pfx:Array) {
  var s = [], p1, p2, pp;
  for (var i = 0; i<pfx.length; i++) {
    if (pfx[i].typ<0) {
      s.push(pfx[i]);
    } else {
      p2 = s.pop();
      p1 = s.pop();
      p2=p2.typ==-1?Number(p2.txt):Number(eval(p2.txt));
      p1=p1.typ==-1?Number(p1.txt):Number(eval(p1.txt));
      var L=s.length;
      s[L]={};
      s[L].txt=_optrs(pfx[i].txt, p1, p2);
      s[L].typ=-1;
    }
  }
  return s[0].txt;
}
//--------主程序段----------
var optrs = setupOptrs();
var TF = new TextFormat();
TF.size = 20;
TF.align = "center";
this.createTextField("hello", 1, 0, 75, 400, 25);
with (hello) {
  type = "dynamic";
  selectable = false;
  setNewTextFormat(TF);
  text="在下面输入表达式";
}
this.createTextField("in_out", 2, 0, 100, 400, 25);
with (in_out) {
  type = "input";
  border = true;
  restrict = "A-Za-z0-9+*/%()=.\\-\\^";
  setNewTextFormat(TF);
}
//提供表达式,输出结果
function out() {
  var ifx = setupIFX(in_out.text, optrs);
  var pfx = ifxToPFX(ifx, optrs);
  in_out.text += "="+pfxToNUM(pfx);
}
in_out.onKillFocus = out;
var myListener = new Object();
Key.addListener(myListener);
myListener.onKeyDown = function() {
if (Key.isDown(Key.ENTER))out();
};
kk=20;
0

评论Comments