求一个表达式运算的程序(100分)

  • 主题发起人 主题发起人 charlyisme
  • 开始时间 开始时间
e猴子.net老兄在playicq上公开了他的代码。你去艘一下
 
var
vScript: Variant;
begin
vScript := CreateOleObject('ScriptControl');
vScript.Language := 'JavaScript';
vScript.Eval(表达式);
end;

这样是最简单的!不过ABS和MAX要改成JavaScript里对应的函数,替换一下就可以了!
 
微软有一个 VC 的Parser 基类 看看还是不错的。
用VB 写过一个
 
听我的,最简单.::建立操作数栈、运算符号栈。构造运算符(包含括弧和表达式结束符)优先级表。编译原理上的例子。根本不用树的!!![:(!]
 
这里非常感谢LeeChange的用2叉树的解答,呵呵,我试了试,非常直观!
我会非常认真地阅读这个程序。
呵呵,还有一个用堆栈实现的没有实现,我会继续学习,继续尝试。
 
to leechange:
您的代码写得很精辟哦,有一点想问一下:
//根据表达式s构造树
function TForm1.MakeTree(s: string): TTree;
中 ....
New(Result);
//找出表达式s中最后一个运算的运算符的位置,放入p中
p:=FindLastOpPos(s);
//???这里为什么要找最后一个运算符,而不是找第一个运算符?有什么区别吗?
if p>0 then
begin
...
您能否说说为什么要找最后一个运算符呢?
 
你看一下程序画出的树就知道了,越靠后运算的运算符越接近树根.
 
to leechange:
"越靠后运算的运算符越接近树根. "?
为什么要越靠后运算的运算符越接近树根??还是不懂,继续请教!
 
准备结题了,呵呵。
to Leechange:
读您的程序受用无穷,不过再问一下,您这个程序怎么改一下可以用sin,cos这类函数呢?
 
要改CalculateTree;
var
a, b:do
uble;
begin
if (Root^.LeftChild=nil) and (Root^.RightChild=nil) then
Result:=StrToFloat(Root^.op)//关键是在这里处理函数.
else
begin
a:=CalculateTree(Root^.LeftChild);
b:=CalculateTree(Root^.RightChild);
case Root^.op[1] of
'+': Result:=a+b;
'-': Result:=a-b;
'*': Result:=a*b;
'/': Result:=a/b
end
end
end;

 
我尝试改了改,呵呵,还没有搞定,所以请教您。
对了,cos,sin这些作为一元运算符时,字符长度是3个,而不再是一个了。原来的程序好像只能处理二元运算符。
 
其实,碰到函数时是在
Result:=StrToFloat(Root^.op)
这句话里改,整个函数体已经是在二叉树的叶结点上了.叶结点的值就是其本身的值.
 
如果函数内容嵌套有表达式呢?
比如cos(2*(3+2)-10),它不是叶节点,它下面还有分支,
那么应该怎么处理呀,呵呵,cos是不是当成一元运算符处理?
 
呵呵,求值过程本身就在递归,如果函数参数是表达是,再递一次又何妨.
 
接受答案了.
 
后退
顶部