如何将字符串公式转换成可运行的数学公式(50分)

  • 主题发起人 主题发起人 yutian0500
  • 开始时间 开始时间
Y

yutian0500

Unregistered / Unconfirmed
GUEST, unregistred user!
我想把'1+3+4/5+8*9',这个字符串转换成可计算的
数学式,1+3+4/5+8*9,如果公式中的数字式表字段或变量,如何处理
 
学过编译原理吗?
学过的话不难,而且网上有现成的控件,输入一个字符串后(任意四则运算),可以得出结果。去找找。
 
http://www.playicq.com/dispdocnew.php?id=1505
名称: 数学函数动态编译器TCompile类 -- 作者:
 
利用sql来处理:
select 1+3+4/5+8*9 ...
变量也一样:)
 
也可以用AdoQuery之类的数据集,利用SQL语句来获得公式结果,如SQL语句为
select 1+3+4/5+8*9
打开后即可用 AdoQuery1.fields[0].asfloat取得其值
 
如何分离出操作数和相关操作符的问题啦,
网上确实有这方面的资料和控件,
RX应该就有吧,我记不清楚了,
实在没有人来说,我就去帮你找找咯,

呵呵~~~~~~~~~~~~~~~~顶~~~~~~~~~~~~~~~~
 
[:D]
给段代码给你看:
我试过了,可以行
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Math;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure Bracket(mText: string
var nLStr, nCStr, nRStr: string);
function Calc(mText: string): string;

implementation

{$R *.dfm}

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
{ Bracket }

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;

end.
 
多人接受答案了。
 
后退
顶部