关键构造出SQL语句就解决问题,你把你的表达式看做字符串就可以,然后对它解析。
解决方案 »
- TreeView1的问题 100分
- 如何截取Windows窗体标题双击事件?????????????
- 用Tidtcpserver/Tidtcpclient组件实现了文件传输完成之后,我的客户端已经关闭了,为什么不能关掉服务器端?
- 阻塞式的INDY如何解决线程关闭超时程序无法退出???
- 请问如何用delphi编写一个最简单的局域网语音聊天程序。
- 我写了一个密码管理软件,大家帮忙试试吧。
- 在看一个源代码,搞不懂是什么意思……
- 系统集成时遇到的问题
- 请问如何用Delphi开发分布式系统?(SOS)
- 如何获得RES(资源文件)的文件数和每个文件的字节数??
- 为什么Trim(Scro.C[j])<>''及 length(Trim(Scro.C[j]))>0 永远也不成立(尽管我查到它不为空也不成立。Scro为记录型,C为字符串数组)
- 怎样把一样时间转为分钟数
其实可以在输入阶段就进行检查这个对+、-、*、\都好判断,就是括号问题比较难以解决。
Bob7946(X度空间)可以提供思路吗
cobi(小新国际):也没有啊
Bob7946(X度空间) :这是公司的要求,我们的经理要这样做,违抗不了的
procedure Test(YourFormula);
var
i, //计数器
temp:Integer;
tempstr:pchar;
Begin
temp:=0; //初始化
i:=0;
while i<length(YourFormula) do
begin
tempstr:=copy(YourFormula,i,1);
if tempstr[0]='(' then
Inc(temp);
if tempstr[0]=')' then
Dec(temp);
Inc(i);
end;
End;
下面的东西很简单,就是判断temp,最好声明temp为全局变量,我就不写了吧~~ 分?
当然有兴趣了,谢谢,我接着………………………………………
读入:
f(x)=x*x+2*x+5*(x+2)
x=3
输出f(x)=3*3+2*3+5*(3+2)=40
TQuery.SQL.Add("select 56*34/34+(2341+1) from dual");
TQuery.Open();
d:double;
d := TQuery.Fields.Fields[0].Value;
我给了一个Component:unit Calculator; interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,DB,dbtables,
contnrs;
type
InvalidateExpressException = class(Exception)
end; PParamRecord = ^TParamRecord;
TParamRecord = record
name: string;
value: Variant;
end; TParamRecords = class
private
FList: TList;
public
procedure Add(Name : string; Value : Variant);
function Delete(Name: string): boolean;
function SetValue(Name: string; Value : Variant):boolean;
function GetValue(Name: string; var Value: Variant): boolean;
procedure Clear;
constructor Create;
destructor Destroy; override;
end; PCalculatorWord = ^TCalculatorWord;
TCalculatorWord = record
wordtype: byte;// 1:data; 2:operator; 3:null;
value: Variant
end; TGetParamsEvent = procedure(Name : string; var Value : Variant) of Object; TCalculator = class(TComponent)
private
{ Private declarations }
protected
FParams : TParamRecords;
FJsgxExpress : String;
TempExpress : String;
DataStack,operatorStack : TStack;
position : integer;
FGetParamsEvent : TGetParamsEvent;
function GetNextToken : TCalculatorWord;
procedure ClearStack;
procedure InitGetToken;
function piror(first : Char; last : Char) : boolean;
function operate(op1,op2 : Variant; operator : Char) : Variant; { Protected declarations }
public
{ Public declarations }
Result : Variant;
property Params : TParamRecords read FParams write FParams;
function Calculate : Variant;
constructor Create(AOwner : TComponent); override;
destructor Destroy ; override; published
property Express : String read FJsgxExpress write FJsgxExpress;
property OnGetParams : TGetParamsEvent read FGetParamsEvent write FGetParamsEvent;
{ Published declarations }
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Calculator', [TCalculator]);
end;constructor TParamRecords.Create;
begin
inherited Create;
FList := TList.Create;
end;destructor TParamRecords.Destroy;
begin
Clear;
FList.Free;
inherited Destroy;
end;procedure TParamRecords.Add(Name : string; Value : Variant);
var
pparam : PParamRecord;
begin
new(pparam);
pparam^.name := Name;
pparam^.value := Value;
FList.Add(pparam);
end;function TParamRecords.Delete(Name : string):boolean;
var
i : integer;
begin
i := 0;
result := false;
while (not result) and (i<FList.Count) do
begin
if PParamRecord(FList.Items[i])^.name = Name then
begin
dispose(PParamRecord(FList.Items[i]));
result := true;
end;
i := i+1;
end;
if result then FList.Delete(i-1);
end;function TParamRecords.SetValue(Name:string;Value:Variant):boolean;
var
i:integer;
begin
result := false;
for i := 0 to FList.Count-1 do
if PParamRecord(FList.Items[i])^.name = Name then
begin
PParamRecord(FList.Items[i])^.value := Value;
result := true;
end;
end;function TParamRecords.GetValue(Name:string;var Value:Variant):boolean;
var
i:integer;
begin
result := false;
for i := 0 to FList.Count-1 do
if PParamRecord(FList.Items[i])^.name = Name then
begin
Value := PParamRecord(FList.Items[i])^.value;
result := true;
end;
end;procedure TParamRecords.Clear;
var
i:integer;
begin
//Free space for items
for i := 0 to FList.Count-1 do
begin
dispose(PParamRecord(FList.Items[i]));
end;
FList.Clear;
end;constructor TCalculator.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
DataStack := TStack.Create;
operatorStack := TStack.Create;
FParams := TParamRecords.Create;
FGetParamsEvent := nil;
FJsgxExpress := '';
end;destructor TCalculator.Destroy;
begin
ClearStack;
DataStack.Free;
operatorStack.Free;
FParams.Free;
inherited;
end;
procedure TCalculator.ClearStack;
var
pFloat:^Variant;
ppChar:^Char;
begin
while DataStack.Count>0 do
begin
pFloat := DataStack.Pop;
Dispose(pFloat);
end;
while operatorStack.Count>0 do
begin
ppChar := operatorStack.Pop;
Dispose(ppChar);
end;
end;function TCalculator.operate(op1,op2:Variant;operator:Char):Variant;
begin
result := 0;
case operator of
'*':result := op1*op2;
'/':if op2 = 0 then raise InvalidateExpressException.Create('计算表达式时发生除零错误,请检查除数。')
else result := op1/op2;
'+':result := op1+op2;
'-':result := op1-op2;
'\':if op2 = 0 then raise InvalidateExpressException.Create('计算表达式时发生除零错误,请检查除数。')
else result := integer(trunc(op1/op2));
end;
end;function TCalculator.piror(first:Char;last:Char):boolean;
begin
result := false;
if ((first = '*') or (first = '/') or (first = '\')) and (last<>'(') then result := true;
if ((first = '+') or (first = '-')) and (last = ')') then result := true;
if (first = ')') or (last = '#') then result := true;
end;function TCalculator.Calculate:Variant;
var
CalculatorWord:TCalculatorWord;
pFloat,pFloat2,pFloat3:^Variant;
ppChar:^Char;
Operator:Char;
IsFinish:boolean;
label OpEnd;
begin
ClearStack;
InitGetToken;
CalculatorWord := GetNextToken;
while CalculatorWord.wordtype<>3 do
begin
case CalculatorWord.wordtype of
1: begin
new(pFloat);
pFloat^ := CalculatorWord.value;
DataStack.Push(pFloat);
end;
2: begin
try
Operator := String(CalculatorWord.value)[1];
IsFinish := false;
while (operatorStack.Count>0) and not IsFinish do
begin
ppChar := operatorStack.Peek;
if (ppChar^ = '(') and (Operator = ')') then
begin
operatorStack.Pop;
goto OpEnd;
end;
if Piror(ppChar^,Operator) then
begin
operatorStack.Pop;
pFloat2 := DataStack.Pop;
pFloat := DataStack.Pop;
new(pFloat3);
pFloat3^ := operate(pFloat^,pFloat2^,ppChar^);
dispose(pFloat);
dispose(pFloat2);
DataStack.Push(pFloat3);
dispose(ppChar);
end
else IsFinish := true;
end;
new(ppChar);
ppChar^ := String(CalculatorWord.value)[1];
operatorStack.Push(ppChar);
OpEnd:
except
on InvalidateExpressException do raise;
on Exception do
raise InvalidateExpressException.Create('表达式计算时出现未知的错误,可能是因为表达式非法.');
end;
end;
end;
CalculatorWord := GetNextToken;
end;
if (operatorStack.Count<>1) or (DataStack.Count<>1) then raise InvalidateExpressException.Create('表达式计算时出现未知的错误,可能是因为表达式非法.')
else
begin
pFloat := DataStack.Pop;
result := pFloat^;
self.Result := pFloat^;
dispose(pFloat);
end;
end;procedure TCalculator.InitGetToken;
begin
position := 1;
TempExpress := FJsgxExpress+'#';
end;function TCalculator.GetNextToken:TCalculatorWord;
var
temp:char;
substr,paramname:string;
i,count,j:integer;
ok:boolean;
value:Variant ;
begin
j := position;
count := length(TempExpress);
if j>count then
begin
result.wordtype := 3;
exit;
end;
while (j<= count) and (TempExpress[j] = ' ') do j := j+1;
temp := TempExpress[j];
if temp in ['+','-','*','/','(',')','\','#'] then
begin
result.wordtype := 2;
result.value := temp;
position := j+1;
end
else if temp in ['0'..'9'] then
begin
i := j;
substr := '';
while (i <= count) and (TempExpress[i] in ['0'..'9','.'] ) do
begin
substr := substr+ TempExpress[i];
i := i+1;
end;
position := i;
try
result.wordtype := 1;
result.value := strtofloat(substr);
except
raise InvalidateExpressException.Create('不合法的常量.');
end;
end
else
begin
substr := copy(TempExpress,j,Length(TempExpress)-j+1);
i := 1;
count := length(substr);
while (i <= count) and not (substr[i] in ['+','-','*','/','(',')','\','#',' ']) do i := i+1;
paramname := copy(TempExpress,j,i-1);
position := j+i-1;
result.wordtype := 1;
value := null;
ok := FParams.GetValue(paramname,value);
if Assigned(FGetParamsEvent) then
FGetParamsEvent(paramname,value); if (not ok) and varisnull(value) then
raise InvalidateExpressException.Create('计算表达式时发生错误,参数'''+paramname+'''没有设值.')
else result.value := value;
end;
end; end.
{
******** 一个表达式运算器(快速优先法) ***********
* 作者: 倪建华 *
* 最后更新:2001.2.24 *
* 信箱: [email protected] *
* 主页: http://njhhack.at.china.com *
* 欢迎使用本软件,转载此源码者请加上以上信息 *
* 请尊重作者劳动,谢谢合作! *
* HackSoft Workgroup 2001.2.24 *
**************************************************
}int fun_min(int km,int *a2)
{
int i,min=25536;
for(i=km-1;i>0;i--)if(min>a2[i])min=a2[i];
for(i=km-1;i>0;i--)if(min==a2[i])break;
return i;
}
float fun_2(int km,float *f1,char *a1,int *a2)
{
int i,j;
float ff1,ff2,ff3;
if(km<=1){ff3=f1[0];}
else if(km<=2){ff1=f1[0];ff2=f1[1];i=1;}
else
{
i=fun_min(km,a2);
if(i>=2)ff1=fun_2(i,f1,a1,a2);
else ff1=f1[i-1];
if(km-i>=2)ff2=fun_2(km-i,f1+i,a1+i,a2+i);
else ff2=f1[km-1];
}
switch(a1[i])
{
case '+':ff3=ff1+ff2;break;
case '-':ff3=ff1-ff2;break;
case '*':ff3=ff1*ff2;break;
case '/':ff3=ff1/ff2;break;
}
return ff3;
}
char *fun_num(char *s1,float *f1)
{
*f1=0;
while(1)
{
if(*s1>='0'&&*s1<='9')*f1=*f1*10+(*s1-'0');
else break;
s1++;
}
return s1;
}
int fun_1(char *s1,float *f1,char *a1,int *a2)
{
int k=0,std=0;
while(1)
{
if(*s1>='0'&&*s1<='9'){s1=fun_num(s1,&f1[k]);k++;}
else if(*s1=='-'¦¦*s1=='+'){a1[k]=*s1;a2[k]=std;s1++;}
else if(*s1=='*'¦¦*s1=='/'){a1[k]=*s1;a2[k]=std+1;s1++;}
else if(*s1=='('){std+=2;s1++;}
else if(*s1==')'){std-=2;s1++;}
else if(*s1==0)break;
}
return k;
}
main(int argc,char *argv[])
{
char *s0,*s1="1+(2*(3-4)+3)/((5+3*2)*3-2)+2*(3-6)";
float f1[100];char a1[100];int a2[100];
int i,j,k;
if(argc<=1)
{
s0=s1;
printf("Error,Useage as follow:\ne4 %s",s0);
}
else
{
s0=argv[1];
while(1)
{
if(*s0==0)break;
if(!(*s0>='0'&&*s0<='9'¦¦*s0=='+'¦¦*s0=='-'¦¦*s0=='/'¦¦*s0=='*'¦¦*s0=='('¦¦*s0==')'))
{
printf("\nError Use:%c",*s0);
return;
}
s0++;
}
s0=argv[1];
printf("Exp=%s",s0);
}
k=fun_1(s0,f1,a1,a2);
printf("\nask=%6.2f ",fun_2(k,f1,a1,a2));
}
到现在还在用
也有现成的控件,只不过我没有怎么用它
tscipt
http://www.csdn.net/soft/openfile.asp?kind=1&id=6111
此算术表达式能够在程序运行时根据输入的变量大小和算术表达式动态解析表达式,得到运算结果。支持多项算术运算符和数学函数如下:: + - * / ^ ( ) mod abs, atan, cos, exp, ln, round, sin, sqrt, sqr, trunc 例如设定a1和a2的大小,就可计算下列表达式: exp(sin(a1)*cos(a2))
[email protected]