求字符串中四则运算的值(50分)

  • 主题发起人 主题发起人 boboqqq
  • 开始时间 开始时间
B

boboqqq

Unregistered / Unconfirmed
GUEST, unregistred user!
求字符串中四则运算的值
如:
s:string
s:='a+b*(c+d)'
计算结果
 
把你大学的数据结构拿出来看看,你不会弄丢了吧
 
字符串能进行四则运算吗?:)即使是用+号,那也只是表示字符串的连接,而不是加法运算
 
s='a+b*(c+d)'
 
这是一种加密的基本办法,我经常用,要的源码的话,请给我妹儿
rain_alinn@163.net
 
翻翻以前学过的数据结构,用堆栈试试!
 
求字符串中四则运算的值
如:
s:string
s:='a+b*(c+d)'其中a,b,c,d为实数
计算结果

 
‘a+b*(c+d)’ 本来就是字符串中的字符。我要求出的结果是实数
 
这样总可以了吧~~~~你开始就不会说清楚啊~~~~

procedure TForm1.Button1Click(Sender: TObject);
var
S :String;
begin
S :=IntToStr(Ord('a')+Ord('b')*(Ord('c')+Ord('d')));
ShowMessage(S);
end;
 
您要的东西叫 expression evaluator - 表达式计算器。网上有很多控件,
比如这个: http://www.bitsoft.com/pub/freestuff/delphi/exprev14.zip
老了些,但是还比较管用。
 
著名的 JEDI 库中也有 expression evaluator,在 JclExprEval.pas 中,
下载地址: ftp://delphi-jedi.org/Code_Library/Release_1_11/JCL.zip
 
如果仅仅是4则运算,那不会困难,主要控制括号的嵌套就行了,这里给你一个示例代码(好早写的,都不知道能不能用了,呵呵):

unit UnitCalcLine;

interface
function CalcLine(CalcString:String;var ErrorPos:integer;var ErrorMsg:string):double;

implementation
uses SysUtils,UnitStack;

var
ErrorCode:integer;
CurPos:integer;
CalcStr:string;

function Proceed(S1:string;S2:string):integer;
const
T:array [0..8] of string=
('!','+','-','*','/','^','(',')','#');
Table:array[0..8,0..8] of integer=
({ ! + - * / ^ ( ) #}
{!}(-1, 1, 1, 1, 1, 1,-1, 1, 1),
{+}(-1, 1, 1,-1,-1,-1,-1, 1, 1),
{-}(-1, 1, 1,-1,-1,-1,-1, 1, 1),
{*}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{/}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{^}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{(}(-1,-1,-1,-1,-1,-1,-1, 0,-2),
{)}(-2, 1, 1, 1, 1, 1,-2, 1, 1),
{#}(-1,-1,-1,-1,-1,-1,-1,-2, 0)
);
var
X,Y:integer;
begin
for X:=0 to 8 do
for Y:=0 to 8 do
if (T[X]=S1) and (T[Y]=s2) then
begin
Result:=Table[X][Y];
exit;
end;
end;

function Operate(A:double;T:string;B:double):double;
begin
if T='+' then
Result:=A+B
else if T='-' then
Result:=A-B
else if T='*' then
Result:=A*B
else if T='/' then
if B=0.0 then
ErrorCode:=1
else
Result:=A/B
else if T='^' then
Result:=Exp(Ln(A)*B)
else
ErrorCode:=4;
end;

function GetObject:string;
var
P:integer;
begin
Result:='';
P:=0;
if CalcStr[Curpos] in ['+','-','*','/','^','(',')','#'] then
begin
Result:=''+CalcStr[Curpos];
Inc(Curpos);
exit;
end;
while CalcStr[Curpos] in ['0'..'9','.'] do
begin
Result:=Result+CalcStr[Curpos];
if CalcStr[Curpos]='.' then
begin
Inc(P);
if P>1 then

/////one error;
end;
Inc(Curpos);
end;
end;


function ValidOperator(Op:string):boolean;
const
T:array [0..7] of string=
('+','-','*','/','^','(',')','#');
var
I:integer;
begin
Result:=False;
for I:=0 to 7 do
if Op=T then Result:=True;
end;


function CalcLine(CalcString:String;var ErrorPos:integer;var ErrorMsg:string):double;
const
ErrorMessage:array [0..6] of string=
((''),
('零不能作为除数!'),
('括号不匹配!'),
('数字 %s 不存在!'),
('对不起,我不认识 %s !'),
('啊!数字太大,我溢出了!'),
('表达式错了!')
);
var
Stack:TStack;
Op:string;
Theta:string;
A,B,C:double;
begin
//Init
ErrorCode:=0;
CurPos:=1;
CalcStr:=CalcString;
Stack:=TStack.Create;
Stack.PushStr('#');
CalcStr:=CalcStr+'#';
Op:=GetObject;
//Start Calc
while (Op<>'#') or (Stack.GetTopStr<>'#') do
begin
if Not ValidOperator(Op) then
begin
Stack.PushInt(StrToFloat(Op));
Op:=GetObject;
end
else
begin
case Proceed(Stack.GetTopStr,Op) of
-2:ErrorCode:=2;
-1://<op;
begin
Stack.PushStr(Op);
Op:=GetObject;
end;
0://=op;
begin
Stack.PopStr
//pop # or ()
Op:=GetObject;
end;
1://>op;
begin
Theta:=Stack.PopStr;
B:=Stack.PopInt;
A:=Stack.PopInt;
C:=Operate(A,Theta,B);
Stack.PushInt(C);
end;
end;
end;
if ErrorCode<>0 then break;
end;
if ErrorCode=0 then
if Stack.IntTop<>1 then
ErrorCode:=6;
if ErrorCode=0 then
begin
Result:=Stack.GetTopInt;
ErrorPos:=0;
end
else
begin
Result:=0;
ErrorPos:=CurPos;
end;
ErrorMsg:=ErrorMessage[ErrorCode];
Stack.Free;
end;



unit UnitStack;

interface
uses sysutils;

const
MAXSIZE=255;

type
TStack=class(TObject)
private
Str:array [0..MAXSIZE] of string;
Int:array [0..MAXSIZE] of double;
protected

public
IntTop:integer;
StrTop:integer;

constructor Create;
function PopStr:string;
function PopInt:double;
function PushStr(S:string):boolean;
function PushInt(I:double):boolean;
function GetTopStr:string;
function GetTopInt:double;
end;

implementation

constructor TStack.Create;
begin
Inherited Create;
IntTop:=0;
StrTop:=0;
end;

function TStack.PopStr:String;
begin
if StrTop=0 then
begin
raise Exception.Create('Error');
exit;
end;
Result:=Str[StrTop];
Str[StrTop]:='';
Dec(StrTop);
end;

function TStack.PopInt:double;
begin
if IntTop=0 then
begin
raise Exception.Create('Error');
exit;
end;
Result:=Int[IntTop];
Int[IntTop]:=0;
Dec(IntTop);
end;

function TStack.PushStr(S:String):Boolean;
begin
if StrTop=MAXSIZE then
begin
raise Exception.Create('Error');
exit;
end;
Inc(StrTop);
Str[StrTop]:=S;
Result:=True;
end;

function TStack.PushInt(I:double):Boolean;
begin
if IntTop=MAXSIZE then
begin
raise Exception.Create('Error');
exit;
end;
Inc(IntTop);
Int[IntTop]:=I;
Result:=True;
end;

function TStack.GetTopStr:string;
begin
Result:=Str[StrTop];
end;

function TStack.GetTopInt:double;
begin
Result:=Int[IntTop];
end;

end.
 
Delphi6第二张光盘中有一个控件Parser,带源代码,很好用
支持四则运算,三角函数,对数指数,幂运算,并可自定义变量
采用准编译方式,速度非常快

若弄不到我可发给你
 
多人接受答案了。
 
后退
顶部