“函数一般的都有吧!”等于没回答哎!
算了,做个仅支持cos的版本吧,理解了加其他函数很容易的,不过函数多了就不能用排列if语句的办法了。
另外,没做错误处理,没做仔细测试,有什么小Bug自己改改吧。能改就说明理解了。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TTree = ^TNode;
TNode = record
op: string;
Value: Double;
LeftChild, RightChild: TTree
end;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function FindLastOpPos(s: string): Integer;
var
i: Integer;
Count: Integer;
begin
Result:=0;
Count:=0;
for i:=Length(s) downto 1 do
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 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;
function 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>1 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 if Pos('cos', LowerCase(s))=1 then
begin
Result^.op:='cos';
Result^.LeftChild:=MakeTree(Copy(s, 5, Length(s)-5));
Result^.RightChild:=MakeTree('0')
end
else
begin
Result^.Op:=s;
Result^.LeftChild:=nil;
Result^.RightChild:=nil
end
end
end
end;
procedure CalculateTree(Root: TTree);
var
a, b: Double;
begin
if (Root^.LeftChild=nil) and (Root^.RightChild=nil) then
Root^.Value:=StrToFloat(Root^.op)
else
begin
CalculateTree(Root^.LeftChild);
CalculateTree(Root^.RightChild);
case Root^.op[1] of
'+': Root^.Value:=Root^.LeftChild^.Value+Root^.RightChild^.Value;
'-': Root^.Value:=Root^.LeftChild^.Value-Root^.RightChild^.Value;
'*': Root^.Value:=Root^.LeftChild^.Value*Root^.RightChild^.Value;
'/': Root^.Value:=Root^.LeftChild^.Value/Root^.RightChild^.Value;
'c': Root^.Value:=Cos(Root^.LeftChild^.Value*Pi/180)
end
end
end;
function IsZero(const Value: Double): Boolean;
begin
Result:=Abs(Value)<1e-5
end;
function GetResult(Root: TTree): string;
var
s1, s2: string;
begin
if Root=nil then
Result:=''
else if IsZero(Root^.Value) then
Result:='0'
else if (Root^.LeftChild=nil) and (Root^.RightChild=nil) then
Result:=Root^.op
else
begin
s1:=GetResult(Root^.LeftChild);
s2:=GetResult(Root^.RightChild);
case Root^.op[1] of
'+': if s1='0' then
Result:=s2
else if s2='0' then
Result:=s1
else
Result:=s1+'+'+s2;
'-': if s2='0' then
Result:=s1
else
begin
if (Root^.RightChild^.op[1] in ['+', '-']) then
s2:='('+s2+')';
if s1='0' then
Result:='(-'+s2+')'
else
Result:=s1+'-'+s2
end;
'*': begin
if (Root^.LeftChild^.op[1] in ['+', '-']) then
s1:='('+s1+')';
if (Root^.RightChild^.op[1] in ['+', '-']) then
s2:='('+s2+')';
Result:=s1+'*'+s2
end;
'/': begin
if (Root^.LeftChild^.op[1] in ['+', '-']) then
s1:='('+s1+')';
if (Root^.RightChild^.op[1] in ['+', '-', '*', '/']) then
s2:='('+s2+')';
Result:=s1+'/'+s2
end;
'c': Result:='cos('+s1+')'
end
end
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Root: TTree;
s: string;
p: Integer;
begin
s:=Edit1.Text;
p:=Pos('=', s);
Root:=MakeTree(Copy(s, 1, p-1));
CalculateTree(Root);
Edit2.Text:=GetResult(Root)+Copy(s, p, Length(s)-p+1);
DestroyTree(Root)
end;
end.