我写这东西的时候没有参考别人的,后来才发现,这不是递归吗? unit jsbds; //计算表达式 //--------------------------------------------// // 汉字最好 2008.11 // // http://blog.youkuaiyun.com/stgsd // //--------------------------------------------// interface uses windows,SysUtils,math; function qbdsz(s:string):double; //取表达式值 implementation var x:array of double; //实数范围可以更改 y:array of string; max:integer; pai,e:double; function qz(s:string):double; //将没有括号的表达式求值 var t:integer; s1:string; begin try //按加减,乘除,乘方,三角函数对数的顺序 t:=pos('+',s); if t>1 then begin s1:=copy(s,1,t-1); delete(s,1,t); result:=qz(s1)+ qz(s);//递归调用 exit; end; t:=pos('-',s); if t>0 then begin if t=1 then s1:='0' else s1:=copy(s,1,t-1); delete(s,1,t); result:=qz(s1)- qz(s); exit; end; t:=pos('*',s); if t>1 then begin s1:=copy(s,1,t-1); delete(s,1,t); result:=qz(s1)* qz(s); exit; end; t:=pos('/',s); if t>1 then begin s1:=copy(s,1,t-1); delete(s,1,t); result:=qz(s1)/qz(s); exit; end; t:=pos('^',s); if t>1 then begin s1:=copy(s,1,t-1); delete(s,1,t); //result:=exp(qz(s)*ln(qz(s1)));没有考虑qz9(s1)为负数的情况 result:=power(qz(s1),qz(s));//用math单元的幂函数 exit; end; t:=pos('sin',s); if t=1 then begin delete(s,1,3); result:=sin(qz(s)); exit; end; t:=pos('cos',s); if t=1 then begin delete(s,1,3); result:=cos(qz(s)); exit; end; t:=pos('arctg',s); if t=1 then begin delete(s,1,5); result:=arctan(qz(s)); exit; end; t:=pos('tg',s); if t=1 then begin delete(s,1,2); result:=sin(qz(s))/cos(qz(s)); exit; end; t:=pos('ln',s); if t=1 then begin delete(s,1,2); result:=ln(qz(s)); exit; end; t:=pos('lg',s); if t=1 then begin delete(s,1,2); //result:=ln(qz(s))/ln(10); result:=log10(qz(s)); exit; end; if (s[1]='p')and(s[2]='i') then begin result:=pai; exit; end; if s[1]='e' then begin result:=e; exit; end; if s[1]='y' then begin delete(s,1,1); result:=x[strtoint(s)]; //将x与y对应 exit; end; result:=StrToFloat(s); except on exception do messagebox(0,'表达式不正确或计算超出范围','这不是耍我吗?',mb_ok); end; end; procedure fenjie(s:string); //分解括号 label xx; var ks,m,n:integer; s1:string; begin n:=0;setlength(y,1); xx: ks:=pos('(',s); //找左括号 if ks>0 then begin for m:=ks to length(s) do begin if s[m]='(' then ks:=m;//第一个右括号之前的左括号 if s[m]=')' then break; //第一个右括号 end; y[n]:=copy(s,ks+1,m-ks-1); //(*),把*存到y数组中 s1:=copy(s,1,ks-1); delete(s,1,m); s:=s1+'y'+inttostr(n)+s; //用yn替代原来的* n:=n+1;setlength(y,n+1); goto xx; //分解其他的括号 end; y[n]:=s; setlength(x,n+1); max:=n; //y数组的上限 end; //如sin(3-2)/(5-8)分解后,y中变成 //y0=3-2 //y1=5-8 //y2=siny0/y1 ,依次计算就可以得到结果 function qbdsz(s:string):double; //s不要有空格,要清除也简单 var r:integer; begin fenjie(s); for r:=0 to max do x[r]:=qz(y[r]);//从0开始计算y[r]值,x[max]就是最后结果 result:=x[max]; end; //计算qbdsz('(sinpi)^2+(cospi)^2')看看应该等于1 initialization //pai:=arctan(1)*4; pai:=pi; //预先弄好圆周率和自然对数的底 e:=exp(1); end.