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

  • 主题发起人 charlyisme
  • 开始时间
C

charlyisme

Unregistered / Unconfirmed
GUEST, unregistred user!
求一个表达式运算的程序
表达式输入是一个串,比如 'ABS(Max(3,2)+2-5-5)',结果输出'5'。
为简化程序,运算符相关的只包括加减,ABS函数,Max/Min函数以及括号。函数应该类似以下方式:
function GetExpressionResult(ExpressionStr:string):string;
请教各位朋友,这个函数应该怎么写?怎么写比较简单!
 
用TParser控件吧,带源代码的
http://vcl.vclxx.org/DELPHI/D32FREE/PARSER10.ZIP
 
另人写的,你的要求可以达到
数学表达式的解析.dll
library fun;
uses
sharemem,
SysUtils,
StdCtrls,
math;
function rapidstrtofun(s:string;x:double):double;
var
posi:array[1..50]of integer;
data:array[1..50]ofdo
uble;
mulsign,plusign:array[1..50]of char;
muldev,addmin:array[1..50]of integer;
{point to the position of data,index of data}
n,n2,n3:integer;
len,i,j:integer;
s1:string;
begin
s:=lowercase(s);
len:=length(s);
if len=1 then
begin
if s='x' then
begin
result:=x;exit;
end;
result:=strtofloat(s);exit;
end;
n:=0;{number of operater=n2+n3}
n2:=0;{number of * and /}
n3:=0;{number of + and -}
{find out the operater}
for i:=2 to lendo
begin
case s of
'*':
begin
inc(n);inc(n2);mulsign[n2]:='*';muldev[n2]:=n;
posi[n]:=i;
end;
'/':
begin
inc(n);inc(n2);mulsign[n2]:='/';muldev[n2]:=n;
posi[n]:=i;
end;
'+':
if (s[i-1]<>'e')=true then
begin
inc(n);inc(n3);plusign[n3]:='+';addmin[n3]:=n;
posi[n]:=i;
end;
'-':
if (s[i-1]<>'e')=true then
begin
inc(n);inc(n3);plusign[n3]:='-';addmin[n3]:=n;
posi[n]:=i;
end;
end;
end;
{pick out the data}
if n=0 then
begin
result:=strtofloat(s);exit;
end;
s1:='';
for i:=1 to posi[1]-1do
begin
s1:=s1+s;
end;

if s1='x' then
data[1]:=x
else
if s1='-x' then
data[1]:=-x
else
data[1]:=strtofloat(s1);
for i:=1 to n-1do
begin
s1:='';
for j:=posi+1 to posi[i+1]-1do
begin
s1:=s1+s[j];
end;
if s1='x' then
data:=x
else
data[i+1]:=strtofloat(s1);
end;
s1:='';
for i:=posi[n]+1 to lendo
begin
s1:=s1+s;
end;
if s1='x' then
data[n+1]:=x
else
data[n+1]:=strtofloat(s1);
{calculate * and /}
for i:=1 to n2do
begin
if mulsign='*' then
data[muldev+1]:=data[muldev]*data[muldev+1]
else
data[muldev+1]:=data[muldev]/data[muldev+1];
end;
for i:=1 to n3-1do
begin
if plusign='+' then
data[addmin[1]]:=data[addmin[1]]+data[addmin[i+1]]
else
data[addmin[1]]:=data[addmin[1]]-data[addmin[i+1]];
end;
if n3=0 then
result:=data[n2+1]
else
result:=data[1]+data[n+1];
end;

function brackets(s:string;x:double):double;register;
var
s0,s1:string;
time:integer;
i,j,k,order,l0:integer;
med:double;
med1,value2:double;
value1:integer;
count:array[1..1000]of integer;
judge:boolean;
Label line1;
begin
line1: order:=pos('((',s);
if(order>0)then
begin
insert('1*',s,order+1);
goto line1;
end;
time:=0;
s0:=s;
judge:=false;
l0:=length(s);
for i:=1 to l0do
begin
if(s='(')then
time:=time+1;
end;
if(time=0)then
judge:=true;
if(time>0)then
begin
for i:=1 to timedo
begin
j:=0;
for order:=1 to l0do
begin
if((s[order]='(')=true)or((s[order]=')')=true)then
begin
j:=j+1;
count[j]:=order;
end;
end;
for k:=1 to j-1do
begin
if(((s[count[k]]='(')=true)and
((s[count[k+1]]=')')=true))then
begin
order:=count[k];
{keep the location of ( }
break;
end;
end;
if(order=1)then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
s1:=floattostr(med);
s:=s0;
delete(s,count[k],count[k+1]-count[k]+1);
insert(s1,s,count[k]);
s0:=s;
l0:=length(s);
end
else
begin
if(((s[count[k]-1]='*')=true)or((s[count[k]-1]='/')=true)or
((s[count[k]-1]='+')=true)or((s[count[k]-1]='-')=true))then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
s:=s0;
s1:=floattostr(med);
delete(s,count[k],count[k+1]-count[k]+1);
insert(s1,s,count[k]);
s0:=s;
l0:=length(s);
continue;
end;

if(s[count[k]-1]='p')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
med:=exp(med);
s1:=floattostr(med);
s:=s0;
delete(s,count[k]-3,count[k+1]-count[k]+4);
insert(s1,s,count[k]-3);
s0:=s;
l0:=length(s);
continue;
end;

if(s[count[k]-1]='g')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
s:=s0;
if(s[count[k]-2]='l')then
begin
med:=Log10(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-2,count[k+1]-count[k]+3);
insert(s1,s,count[k]-2);
s0:=s;
l0:=length(s);
end
else
begin
if(s[count[k]-2]='t')then
begin
delete(s,count[k]-2,l0-count[k]+3);
if((s='')=false)then
begin
if(s[count[k]-3]='c')then
begin
med:=cotan(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-3,count[k+1]-count[k]+4);
insert(s1,s,count[k]-3);
s0:=s;
l0:=length(s);
end
else
begin
med:=tan(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-2,count[k+1]-count[k]+3);
insert(s1,s,count[k]-2);
s0:=s;
l0:=length(s);
end;
end
else
begin
med:=tan(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-2,count[k+1]-count[k]+3);
insert(s1,s,count[k]-2);
s0:=s;
l0:=length(s);
end;
end;
end;
continue;
end;
if(s[count[k]-1]='^')then
begin
value1:=pos(',',s);
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,value1);
value2:=rapidstrtofun(s,x);
s:=s0;
delete(s,value1,l0-value1+1);
delete(s,1,count[k]);
med1:=rapidstrtofun(s,x);
med:=power(med1,value2);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-1,count[k+1]-count[k]+2);
insert(s1,s,count[k]-1);
s0:=s;
l0:=length(s);
continue;
end;
if(s[count[k]-1]='s')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
med:=cos(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-3,count[k+1]-count[k]+4);
insert(s1,s,count[k]-3);
s0:=s;
l0:=length(s);
continue;
end;
if(s[count[k]-1]='h')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
s:=s0;
if(s[count[k]-2]='s')then
begin
med:=cosh(med);
end
else
begin
med:=sinh(med);
end;
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-4,count[k+1]-count[k]+5);
insert(s1,s,count[k]-4);
s0:=s;
l0:=length(s);
continue;
end;
if(s[count[k]-1]='t')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
med:=sqrt(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-4,count[k+1]-count[k]+5);
insert(s1,s,count[k]-4);
s0:=s;
l0:=length(s);
continue;
end;
if(s[count[k]-1]='r')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
med:=sqr(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-3,count[k+1]-count[k]+4);
insert(s1,s,count[k]-3);
s0:=s;
l0:=length(s);
continue;
end;
if(s[count[k]-1]='n')then
begin
delete(s,count[k+1],l0-count[k+1]+1);
delete(s,1,count[k]);
med:=rapidstrtofun(s,x);
s:=s0;
if(s[count[k]-2]='l')then
begin
med:=ln(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-2,count[k+1]-count[k]+3);
insert(s1,s,count[k]-2);
s0:=s;
l0:=length(s);
end
else
begin
med:=sin(med);
s:=s0;
s1:=floattostr(med);
delete(s,count[k]-3,count[k+1]-count[k]+4);
insert(s1,s,count[k]-3);
s0:=s;
l0:=length(s);
end;
continue;
end;
end;
end;
brackets:=rapidstrtofun(s,x);
end;

if(judge=true)then
brackets:=rapidstrtofun(s,x);
end;
exports
brackets name 'fun';
begin
end.
 
上网找关键字吧
CAJSCRPT.ZIP
TCajScript 是一个 Pascal 程序语言解释器类,提供多项字符串处理函式 ( 例如 Pos、Copy、Delete、Insert、Uppercase、IntToStr、StrToInt、Chr 及 Ord) ( 1.4 版,附源码 ),作者 : Carlo Kok。
COMPILER.ZIP
一组制作编译器的构件,包含 Lexical 及 Syntax Parser ( 1.02 版,附源码 ),作者: Max Belugin。
COPASCAL.ZIP
将 Turbo Pascal 上的 CoPascal 编译器及解释器 ( compiler/interpreter ) 移植到 Delphi ( 2.01 版,附源码 ) ,作者 : Colin LAPLACE。
DELPHIN.ZIP
Delphi Object Pascal 的解释器, VCL 构件及 .DFM 文件都能够显示执行 ( 1.21 版,附源码 ), 作者 : Sergey Kurinny。
EXPRESS.ZIP
能够计算数学运算式的构件 ( 2.0 版,附源码 ),作者 : Renate Schaaf。
EXPREV.ZIP
是一个能够解析数学运算式,并且计算其值的构件,支持四则运算、三角函数、指数对数、次方运算及使用者自定变量 ( 1.40 版,附源码 ),作者 : BitSoft Development, L.L.C.。
可以用来产生密码,比如真正的密码是[(sin(a)+cos(b))/c]那么只要传送abc给对方就行了
EXPREVAL.ZIP
Expressions 单构件能够解析数学运算式的单元 ( 1.0.1 版,附源码 ),作者 : Production Robots Engineering Ltd。
FEVAL.ZIP
TEval 是一个能够解析数学运算式的构件 ( 1.0 版,附源码 ),作者 : Giuseppe Stalteri。
MPASLEX2.ZIP
TmPasLex 是一个快速解析 Pascal 程序语言语法 Token 的构件 ( 1.89 版,附源码 ),作者 : Martin Waldenburg。
MWPASPAR.ZIP
TmPasParser 一个解析 Pascal 程序语言语法的 Parser 构件 ( 1.91 版 ,附源码 ) ,作者:Martin Waldenburg。
PSCRIPT.ZIP
P-Script 是类似 Pascal 的程序语言,此构件提供解译 P-Script 程序语言的能力 ( 0.05 Beta 版,无源码 Delphi 3.0 适用 ) ,作者 : Kirill B. Kuznetsov。
TINYPAS.ZIP
TinyPascal 编译器是一个小型精简的 Pascal 程序语言编译器 ( 附源码 ),作者 : Colin LAPLACE。
XAEVAL.ZIP
是一个能够解析数学运算式的构件 ( 1.1 版,附源码 )。作者 : Lincoln Birnie。
Z_PARSER.ZIP
能够解析数学运算式的单元 ( 1.0 版,附源码 ),作者 : Antonie Baars。
非常小,很好
 
一个一元运算符,一个二元运算符,只有加减?
呵呵,楼主的意思好像是要一个算法框架,可惜我给不出来。
 
楼主要是想用用而已呢,楼上已经有很多了.
楼主要是想知道原理呢,就要去看看数据结构上关于二叉树的遍历的章节了.
 
to studymore:呵呵,被您看出来了,我只需要一个算法框架。
to leechange:谢谢您的指点,我会去看看数据结构上关于二叉树的遍历的章节了,不知道应该看哪本书?
另外好像可以用两个栈,用一个栈存放数字,用另一个栈存放运算符,呵呵,不知道是怎么实现的。
请教!
 
to charlyisme:
一点不错,表达式求值确实有两种经典算法.一个是构造二叉树,然后后序遍历,就是逆波兰.
另一个就是用两个栈,一个放数,一个放运算符,根据将入栈的运算符和栈顶运算符决定做什么操作.
个人感觉用第一种的最正统,代码也很清晰,显得有条有理.但我自己上个月在dfw上做了个表达式求值,偏偏两个都没用,用了一种最笨的小学老师教的方法.哈哈.
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1753136
 
表达式运算我也写过,用递归,其实原理跟二叉树差不多,
反正表达式不长,不用担心栈溢出。跟TParser比较了一下,效率
差了很多,我觉得TParser还是不错的,开放源代码,有兴趣可以好好研究一下。
 
prExpr 这个函数库不错 要的话拿google 搜一下
它的demo 和思路决定精练 可以外挂解析函数

支持的函数是:
arithmetic...
TRUNC, ROUND, ABS, ARCTAN, COS, EXP, FRAC, INT,
LN, PI, SIN, SQR, SQRT, POWER
string...
UPPER, LOWER, COPY, POS, LENGTH
 
转贴一篇c51bbs的讨论,不过是单片机实现的,希望对你有用
初学者:请各位不吝指点:如何用单片机制作一个普通计算器? [Fanyx] [7次] 01-12-9 下午 09:00:52
语法分析器 [wisdom] [32次] 01-12-11 下午 01:16:22
1.首先从键盘上能够得到键入的数字和运算符信息
2.然后将键盘缓冲区的数据和运算符进行二叉树左序到“后序”调整:
such as: 1+2+3
(+)
/ /
(+) (3)
/ /
(1) (2)
接收排序:1 + 2 + 3
调整为: ((1,2)+),3 )+
3. 编程实现采用堆栈处理: 两个堆栈, 数据栈,操作符栈,
such as:push “1" to 数据栈
push ”+“ to 操作符栈
push ”2" to 数据栈
get “=” 将栈顶的两个数据进行操作栈中指定的操作,将结果压栈
以此类推。
good [lezi] [2次] 01-12-11 下午 01:34:16
去把proteus找来安装,里面有计算器的例子,有电路图,有程序,还可以模拟运行试试。 [qiang] [15次] 01-12-11 下午 02:21:28
这个算法其实对初学者难度很大 [xzm0662] [18次] 01-12-11 下午 02:25:06
没有良好的数据结构基础,难以实现这个二叉树操作,那个后序表达式好像叫“逆波兰表达
式”,编译原理和一些数据结构的书上可能有。
我提一个算法,效率不高,但是简单:
字符串扫描处理:
假定表达式存于 buf[]="1+2*3/4-5"
扫描逻辑:设定指针指向第一个字符point=0;
开始扫描,point++,监测buf[point]=运算符,记住这一个运算符,然后找下个运算符,如
果下一个运算符优先级不比当前的运算符优先级高,则进行运算,把运算符和数删除,把结
果添回表达式;否则继续向下寻找运算的位置,直到没有运算符。
上式计算:
第一步:point搜索,发现运算符“+”,然后找到下一个运算符“*”,下一个优先级高。
因此不运算。
第二步:point指向“*”,找到下一个运算符“/”,下一个优先级不比当前高。因此运
算。buf调整buf="1+6/4-5".
第三步:point调整到“+”,继续上述运算。
高中时用basic实现过,大约40多行
 
to leechange:
惭愧,查了数据结构的书籍,也没能实现用标准的二叉树或者堆栈实现的表达式运算的代码。
希望哪位朋友指点!
 
同意 LeeChange 一个是构造二叉树,然后后序遍历
 
听我的,最简单.::建立操作数栈、运算符号栈。构造运算符(包含括弧和表达式结束符)优先级表。
 
希望哪位能给一个leechange说的两种标准算法的一种实现。谢谢!
 
做了个用2叉树求的,多加了求逆波兰式和画出树的功能,要直观一点.
object Form1: TForm1
Left = 192
Top = 107
Width = 769
Height = 480
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
WindowState = wsMaximized
OnClose = FormClose
PixelsPerInch = 96
TextHeight = 13
object PaintBox: TPaintBox
Left = 0
Top = 41
Width = 761
Height = 412
Align = alClient
end
object Panel: TPanel
Left = 0
Top = 0
Width = 761
Height = 41
Align = alTop
TabOrder = 0
object ExpressEdit: TEdit
Left = 9
Top = 9
Width = 168
Height = 21
TabOrder = 0
end
object CalculateButton: TButton
Left = 280
Top = 8
Width = 75
Height = 25
Caption = 'Calculate'
TabOrder = 1
OnClick = CalculateButtonClick
end
object DrawButton: TButton
Left = 456
Top = 8
Width = 75
Height = 25
Caption = 'Draw'
TabOrder = 2
OnClick = DrawButtonClick
end
object ValueEdit: TEdit
Left = 536
Top = 10
Width = 209
Height = 21
TabOrder = 3
end
object FormatButton: TButton
Left = 368
Top = 8
Width = 75
Height = 25
Caption = 'Format'
TabOrder = 4
OnClick = FormatButtonClick
end
object MakeTreeButton: TButton
Left = 192
Top = 8
Width = 75
Height = 25
Caption = 'MakeTree'
TabOrder = 5
OnClick = MakeTreeButtonClick
end
end
end
 
下面是代码,核心部分是MakeTree.
至于画树的代码不看也罢,仅仅为了直观一点而已.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TTree = ^TNode;
TNode = record
op: string;
LeftChild, RightChild: TTree
end;

TForm1 = class(TForm)
Panel: TPanel;
ExpressEdit: TEdit;
CalculateButton: TButton;
DrawButton: TButton;
ValueEdit: TEdit;
FormatButton: TButton;
MakeTreeButton: TButton;
PaintBox: TPaintBox;
procedure FormatButtonClick(Sender: TObject);
procedure CalculateButtonClick(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure MakeTreeButtonClick(Sender: TObject);
procedure DrawButtonClick(Sender: TObject);
private
{ Private declarations }
function FindLastOpPos(s: string): Integer;
procedure DestroyTree(Root: TTree);
public
{ Public declarations }
Root: TTree;
function MakeTree(s: string): TTree;
function FormatTree(Root: TTree): string;
function CalculateTree(Root: TTree):do
uble;
procedure DrawTree(Root: TTree;
Top, Left, Right: Integer);
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
{ TForm1 }
//找出表达式s中最后一个运算的运算符的位置
function TForm1.FindLastOpPos(s: string): Integer;
var
i: Integer;
Count: Integer;
begin
Result:=0;
Count:=0;
for i:=Length(s)do
wnto 1do
case s of
'(' : Dec(Count);
')' : Inc(Count);
'+', '-': if Count=0 then
begin
Result:=i;
Exit
end;
'*', '/': if (Count=0) and (Result=0) then
Result:=i
end
end;

procedure TForm1.DestroyTree(Root: TTree);
//回收内存
begin
if Root=nil then
Exit;
if Root^.LeftChild<>nil then
DestroyTree(Root^.LeftChild);
if Root^.RightChild<>nil then
DestroyTree(Root^.RightChild);
Dispose(Root)
end;

//根据表达式s构造树
function TForm1.MakeTree(s: string): TTree;
var
Len: Integer;
p: Integer;
begin
if s='' then
Result:=nil
else
begin
Len:=Length(s);
if (s[1]='(') and (s[Len]=')') then
Result:=MakeTree(Copy(s, 2, Len-2))
else
begin
New(Result);
p:=FindLastOpPos(s);
if p>0 then
begin
Result^.op:=s[p];
Result^.LeftChild:=MakeTree(Copy(s, 1, p-1));
Result^.RightChild:=MakeTree(Copy(s, p+1, Len-p))
end
else
begin
Result^.Op:=s;
Result^.LeftChild:=nil;
Result^.RightChild:=nil
end
end
end
end;

//根据树Root输出逆波兰式(后序)
function TForm1.FormatTree(Root: TTree): string;
begin
if Root=nil then
Result:=''
else
Result:=FormatTree(Root^.LeftChild)+' '+FormatTree(Root^.RightChild)+' '+Root^.op
end;

//根据树计算结果(后序)
function TForm1.CalculateTree(Root: TTree):do
uble;
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;

//画树(先序)
procedure TForm1.DrawTree(Root: TTree;
Top, Left, Right: Integer);
var
Mid: Integer;
begin
PaintBox.Canvas.TextOut(Left+(Right-Left-PaintBox.Canvas.TextWidth(Root^.op)) div 2,
Top, Root^.op);
if (Root^.LeftChild<>nil) and (Root^.RightChild<>nil) then
begin
Mid:=Left+(Right-Left) div 2;
PaintBox.Canvas.MoveTo(Mid, Top+PaintBox.Canvas.TextHeight(Root^.op)+2);
PaintBox.Canvas.LineTo(Mid, Top+PaintBox.Canvas.TextHeight(Root^.op)+10);
PaintBox.Canvas.LineTo(Left+(Mid-Left) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+10);
PaintBox.Canvas.LineTo(Mid+(Right-Mid) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+10);
PaintBox.Canvas.MoveTo(Left+(Mid-Left) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+10);
PaintBox.Canvas.LineTo(Left+(Mid-Left) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+18);
PaintBox.Canvas.MoveTo(Mid+(Right-Mid) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+10);
PaintBox.Canvas.LineTo(Mid+(Right-Mid) div 2, Top+PaintBox.Canvas.TextHeight(Root^.op)+18);
DrawTree(Root^.LeftChild, Top+PaintBox.Canvas.TextHeight(Root^.op)+20, Left, Mid);
DrawTree(Root^.RightChild, Top+PaintBox.Canvas.TextHeight(Root^.op)+20, Mid, Right)
end
end;

procedure TForm1.FormatButtonClick(Sender: TObject);
begin
ValueEdit.Text:=FormatTree(Root)
end;

procedure TForm1.CalculateButtonClick(Sender: TObject);
begin
ValueEdit.Text:=FloatToStr(CalculateTree(Root))
end;

procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
DestroyTree(Root)
end;

procedure TForm1.MakeTreeButtonClick(Sender: TObject);
begin
DestroyTree(Root);
Root:=MakeTree(ExpressEdit.Text)
end;

procedure TForm1.DrawButtonClick(Sender: TObject);
begin
PaintBox.Canvas.FillRect(PaintBox.ClientRect);
DrawTree(Root, 10, 0, PaintBox.Width)
end;

end.
 
不如用控件
前人早写好了
何必再辛苦自己
 
程序没有做正确性判断.楼主理解后可以很轻易的加上.
 
顶部