请看这个算法怎么写,谢谢了.(100分)

  • 主题发起人 主题发起人 9861
  • 开始时间 开始时间
9

9861

Unregistered / Unconfirmed
GUEST, unregistred user!
有 a,b,c,c参数,用户可以用+,-,*,/.()进行任意组合成公式,(如a*(b+c)/d)然后我根据他的组合要算出数来S.这个算法谁给提供一下,谢谢了.
 
编译原理中有现成的算法
 
或者结合数据库 交给SQL语句去完成计算。
 
论坛上有这样的东西找找看
 
建立六个按钮,写上六种运算符号,然后再建立四个按钮,代表四个参数,在每个按钮上写对应的代码,如参数a的按钮上写
sStr := sStr + a;
+号的按钮上写 sStr := sStr + '+';
参数b的按钮上写 sStr := sStr + b;
这样用户点a+b后出来的字符串就是 a + b;这样就可以了,其他按钮类似
 
晕,拼字符串俺也会.我要的是拼成字符串后我怎么得到计算的结果.
 
你是算24点啊,靠自己排列组合吧。
 
function str_Value(ss:string):integer;
const scopt:string[7]=')*/+-(@';
sclvl:array [1..7] of byte=(3,3,3,2,2,1,1);
var sw2,sw3:integer; ssop,ss1:string; sc,sc3:char; s1,s2,s3:byte;
swval:array [1..16] of integer;
sbval:byte;
begin
sbval:=0; ss:=ss+'@'; ss1:=''; ssop:='@';
while ss>'' do begin
sc:=ss[1]; delete(ss,1,1); s1:=pos(sc,scopt);
if s1=0 then ss1:=ss1+sc
else begin
if ss1>'' then begin
inc(sbval); swval[sbval]:=StrToInt(ss1); ss1:='';
end;
s2:=sclvl[s1];
repeat
sc3:=ssop[Length(ssop)]; if (sc='@')and(sc3='@') then break;
s3:=sclvl[pos(sc3,scopt)];
if sc=')' then begin
if sc3='(' then begin
SetLength(ssop,Length(ssop)-1); break;
end;
end else begin
if (s2>s3)or(sc='(') then begin
ssop:=ssop+sc; break;
end;
end;
sw3:=swval[sbval]; dec(sbval); sw2:=swval[sbval];
SetLength(ssop,Length(ssop)-1);
case sc3 of
'+':sw2:=sw2+sw3;
'-':sw2:=sw2-sw3;
'*':sw2:=sw2*sw3;
'/':sw2:=sw2 div sw3;
end;
swval[sbval]:=sw2;
until false;
end;
end;
Result:=swval[1];
end;
 
不是用堆栈么??然后按优先及匹配算出来啊。
 
上次说得不够详细,这次补上,edit2.text就是最后拼出的字符串
uses
Math;
procedure Bracket(mText: string; var nLStr, nCStr, nRStr: string);
var
L, R: Integer;
I: Integer;
B: Boolean;
begin
nLStr := '';
nCStr := '';
nRStr := '';
B := True;
L := 0;
R := 0;
for I := 1 to Length(mText) do
if B then begin
if mText = '(' then
Inc(L)
else if mText = ')' then
Inc(R);
if L = 0 then
nLStr := nLStr + mText
else if L > R then
nCStr := nCStr + mText
else B := False;
end else nRStr := nRStr + mText;
Delete(nCStr, 1, 1);
end;

function Calc(mText: string): string;
var
vText: string;
function fCalc(mText: string): string;
var
vLStr, vCStr, vRStr: string;
I, J, K, L: Integer;
begin
L := Length(mText);
if Pos('(', mText) > 0 then begin
Bracket(mText, vLStr, vCStr, vRStr);
Result := fCalc(vLStr + fCalc(vCStr) + vRStr);
end else if (Pos('+', mText) > 0) or (Pos('-', mText) > 0) then begin
I := Pos('+', mText);
J := Pos('-', mText);
if I = 0 then I := L;
if J = 0 then J := L;
K := Min(I, J);
vLStr := Copy(mText, 1, Pred(K));
vRStr := Copy(mText, Succ(K), L);
if vLStr = '' then vLStr := '0';
if vRStr = '' then vRStr := '0';
if I = K then
Result := FloatToStr(StrToFloat(fCalc(vLStr)) + StrToFloat(fCalc(vRStr)))
else Result := FloatToStr(StrToFloat(fCalc(vLStr)) - StrToFloat(fCalc(vRStr)))
end else if (Pos('*', mText) > 0) or (Pos('/', mText) > 0) then begin
I := Pos('*', mText);
J := Pos('/', mText);
if I = 0 then I := L;
if J = 0 then J := L;
K := Min(I, J);
vLStr := Copy(mText, 1, Pred(K));
vRStr := Copy(mText, Succ(K), L);
if vLStr = '' then vLStr := '0';
if vRStr = '' then vRStr := '0';
if I = K then
Result := FloatToStr(StrToFloat(fCalc(vLStr)) * StrToFloat(fCalc(vRStr)))
else Result := FloatToStr(StrToFloat(fCalc(vLStr)) / StrToFloat(fCalc(vRStr)))
end else if Pos('_', mText) = 1 then
Result := FloatToStr(-StrToFloat(fCalc(Copy(mText, 2, L))))
else Result := FloatToStr(StrToFloat(mText));
end;
var
I, L: Integer;
begin
vText := '';
L := Length(mText);
for I := 1 to L do
if (mText = '-') and (I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')'])) then
if (I = 1) or ((I > 1) and (mText[Pred(I)] in ['*', '/'])) then
vText := vText + '_'
else if ((I > 1) and (mText[Pred(I)] in ['+', '-'])) or
((I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')']))) then
vText := vText + '+_'
else vText := vText + mText
else vText := vText + mText;
Result := fCalc(vText);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Edit1.Text := Calc(Edit2.Text);
end;
 
谢谢kangpengjie兄了,不过算法有点Bug:
*和/应是平级的,你的好象*比除高一级:(
如:4+4/4*3 会得到4.333333,其实应是7

另外foam兄的返回值不是结果啊..

谢谢再次关注..
 
to 9861:
晕!你怎么试的?
新建一个form,放上三个控件:edit1, label1, button1
edit1.text:='4+4/4*3';

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:=IntToStr(str_Value(Edit1.Text));
end;
 
呵呵呵,感谢各位研究算法的兄弟们了.
我突然间想到了一个方法,试了比较简单,说与大家:
利用数据库,呵呵.例如SQL SERVER
@a char(1),//+
@b char(1),//-
@c char(1),//*
@d char(1),//除
@value1 decimal(10,2),
@value2 decimal(10,2),
@value3 decimal(10,2),
@value4 decimal(10,2),
declare @result varchar(500)
select @result =@value1+@a+ @value2+@b+@value3+@c+@value4
pirnt @result
呵呵,甚至连@result我也可以传入,然后让SQL Server自己去分析得到结果吧.感谢几位了.
 
一个简洁的办法:

uses ComObj;

// 计算表达式
function ExpressCalc(exp: string): real;
var
co: Variant;
begin
Co := CreateOleObject('ScriptControl');
co.Language := 'VBScript';
Result := co.Eval(exp);
end;

// 测试
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(FormatFloat('0.####',ExpressCalc(Edit1.Text)));
end;
 
高级计算器 V1.0 (含代码)
http://www.2ccc.com/article.asp?articleid=252
 

Similar threads

回复
0
查看
999
不得闲
D
回复
0
查看
887
DelphiTeacher的专栏
D
后退
顶部