在delphi6中如何使程序按照我在edit框中输入的算式来运算?

uniddelphi 2004-04-26 09:21:53
在delphi6中如何使程序按照我在edit框中输入的算式来运算?

edit框中输入算式时使用pascal格式的
...全文
118 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
sandyboy 2004-04-28
  • 打赏
  • 举报
回复
哦,我开始没有看清楚你的问题,我以为是就是想实现在EDIT中输入计算式,然后显示出结果呢!
我发的就是JAVA的脚本来实现运算的!如果要以PASCAL格式,你可以去搜一下关于脚本编译的,我记得以前看到过!
呵呵,至于搜索,我们公司的网速不行,根本就别想全文搜索或大类搜索!我也只是能在小类进行搜索!
uniddelphi 2004-04-27
  • 打赏
  • 举报
回复
找到一个“数学公式解析器”
delphifans上下载的

不知道怎么麽用,里面有一堆.pas .dcu

具体我要用的应该是哪一个呢?
sandyboy 2004-04-27
  • 打赏
  • 举报
回复
这个问题已经有N个都问过了,下次先搜一下再问好了。
但是我们专家分就。。。。。。。。。“:)
sandyboy 2004-04-27
  • 打赏
  • 举报
回复
uses comobj;

var
vScript: Variant;
str:string;
begin
str:='5+(5-2)*3-7';
vScript:=CreateOleObject('ScriptControl');
vScript.Language := 'JavaScript';
str:=vScript.Eval(str);
showmessage(str);
end;
这个很简单而且好用!楼主可以自己试试!转载!
uniddelphi 2004-04-27
  • 打赏
  • 举报
回复
“建议看看编译原理,将算式表示成三元式或者四元式,或者逆波兰后缀”
头好晕阿

在搜索引擎上找了一翻了
没找到那个控件
知道那控件确切的名字么?
qizhanfeng 2004-04-27
  • 打赏
  • 举报
回复
up
飞翔的老虎 2004-04-27
  • 打赏
  • 举报
回复
建议看看编译原理,将算式表示成三元式或者四元式,或者逆波兰后缀
qingenerp 2004-04-27
  • 打赏
  • 举报
回复
有这样的控件,不用自己写代码的,在网上搜一下把!
顶一下!!!
「已注销」 2004-04-27
  • 打赏
  • 举报
回复
我建议用二叉树来实现
yinzhiw 2004-04-27
  • 打赏
  • 举报
回复
关注一下
uniddelphi 2004-04-27
  • 打赏
  • 举报
回复
楼上的
在哪里能找到这个控件阿?
chengongpu 2004-04-27
  • 打赏
  • 举报
回复
绝对有办法。网上有一个《数学公式自动计算》的控件,好象这么写。你把ocx下载后,通过接口可以直接用edit中的计算方法。如果错误还会告诉你错误的原因。。很帮的控件。。
wangxiangsjz 2004-04-27
  • 打赏
  • 举报
回复
不行
uniddelphi 2004-04-27
  • 打赏
  • 举报
回复
打个比方
我的程序中有这么一段
FUNC:= Sqr(X)*(Sqr(X) - 2) * Sin(X);

这个X方乘(X方-2)乘sinX,就是我在edit框中输入的内容,我只是想能把这个edit框中的内容能加入到FUNC:=后面
试过FUNC:=edit1.text; 不行
uniddelphi 2004-04-27
  • 打赏
  • 举报
回复
to sandyboy(雨霆)

这个论坛的搜索方式我不太会用
搜不到我要的东西啊

你能给我个链接么?
mzdot 2004-04-26
  • 打赏
  • 举报
回复
你以为pascal是解释执行的?
miky 2004-04-26
  • 打赏
  • 举报
回复
那么谁帮你把算式编译成机器码呢?
uniddelphi 2004-04-26
  • 打赏
  • 举报
回复
汗汗

应该灭有这么麻烦吧

只是要把edit框中按pascal格式输入的运算式读入到程序中
直接调用这一段算式
miky 2004-04-26
  • 打赏
  • 举报
回复
数据结构(PASCAL语言实现)书上讲述了一个把所有符号和数字推堆栈的方法实现的表达式解析,给你一段网上找到的例子:
一款设计精巧的表达式解析器
---- 开发MIS系统时,报表设计中经常会碰到表达式解释器,完成用户自定义的公式运算。这种程序的设计需要有比较高的技巧,以下介绍一款用DELPHI4.0开发的程序[程序重在算法,语言特性很少,用其它语言的人也能读懂],只要按自已的要求稍加修改,即可做成组件或全局方法发部。它支持 "加[+]、减[-]、乘
  • 、除
  • [/]、商[$:两整数相除,结果的整数部分]、模[%]、括号[()]"四则混合运算,支持"与[&]、或[|]、异或[^]、左移[< ]、右移[ >]和非[!]"逻辑运算功能,同时它们可以出现在同一个表达式中,它们的优先级依次为括号、非、与或异或左右移、乘除商模、加减。如式:12.45+3*16 >2*(3+6*(3+2)-1)=12.45+3*4*32,计算结果为:396.45。程序包括两大部分功能:表达式拆解、因子计算,分别由两个类TBdsProc和TPUSHPOP完成。具体如下:

    CDIKind=record
    case id: Boolean of
    True: (dval: Double);
    False: (ival: Integer);
    end;
    CDKind:区别表达式中的整数和浮点数类型,
    因为有些运算符不支持浮点数(如逻辑运算)。

    ValKind = CDIKind;
    TBdsProc = class
    private
    Fghpd : Integer;//识别并标记左右括号是否成对出现
    function IsCalcFh(c: Char): boolean;
    //判别一个字符是否运算符
    function CopyRight(abds: String;start: Integer):
    String;//截取字符串表达式
    function BdsSs(var abds: String): ValKind;
    //返回一个子表达式的值
    function BdsYz(var abds: String): ValKind;
    //表达式因子,如:15、(13+5)
    function BdsItm(var abds: String): ValKind;
    //读取表达式中的一个因子
    public
    function CalcValue(const bds: String): ValKind;
    //返回计算结果
    end;

    TPUSHPOP = class
    private
    ffh: array [0..2] of Char;//符号数组
    value: array [0..3] of CDIKind;//值数组
    flevel: Byte;//因子个数
    fisfh: Boolean;//识别等待输入值或运算符
    fisnot: Boolean;//识别待计算数据项是否执行非运算
    function Calcsj(av1,av2: CDIKind;fh: Char): CDIKind;
    //执行两个数值的四则运算
    function Calclg(av1,av2: CDIKind; fh: Char): CDIKind;
    //执行两个数的逻辑运算
    procedure Calccur;{当输入数据项满足四个数后
    [依运算优先级层数求得,见下述算式解析原理]执行中间运算}
    function IsLgFh(fh: Char): Boolean;
    //一个符号是否逻辑运算符
    function IsCcFH(fh: Char): Boolean;
    // 一个符号乘除商模运算符
    public
    constructor Create;
    procedure PushValue(avalue: CDIKind);//存入一个数据项
    procedure PushFh(afh: Char);//存入一个符号
    function CalcValue: CDIKind;//计算并返回值
    end;

    ---- 表达式解析基本原理:

    ---- 1.表达式处理:

    ---- 表达式的一个个数据项组成,中间由运算符连接,每个数据项为一个分析基本分析单元。表达式中如果包含有改变运算优先级别的括号运算,先计出括号中式子的值,再把该值当一个数据项处理,这一点在程序设计中只要运用递归功就能实现。

    ---- 2.数据项计算处理

    ---- a >非运算:

    ---- 它为单目运算符,级别最高,在存入符号时做标记,存入数据时即时计算并去除标记。

    ---- b >表达式运算:

    ---- 设f1、f2、f3分别表示一二三级运算符,V1、V2、V3、V4分别表示顺序四个数,则极端表达式模型为R=V1 f1 V2 f2 V3 f3 V4 …,计算时顺序应为 R=…V4 f3 V3 f2 V2 f1 V1。为了简化运算,把其中运算级别最高的逻辑运算在存入数据时先计算完成, 初始化时设V1=0,第一个运算符设为'+'。则公式化为: R=…V4 f2(f1) V3 f2(f1) V2 f1 V1。这样,当V2与V3间的运算符级别为f2时,V4与V3间的运算符级别< =f2,则:V2 =(V2与V3计算值),V3后的值和运算符前移;若V2与V3间的运算级别为f1,可先算V1与V2,V2以后的值和运算符前移。则计算后的表达式为:R=V3 f2(f2) V2 f1 V1刚好满足循环取数条件。

    ---- 3.实现:

    ---- 程序比较长(TBdsProc和TPUSHPOP的源代码合计长度为400多行),完整代码见附件,以下对一些重要实现方法做介绍:

    ---- < 1 >表达式拆解:由方法BdsSs和BdsYz完成表达式拆解和因子处理

    function TBdsProc.BdsSs(var abds: String): ValKind;
    var
    c: Char;
    lpp: TPushPop;
    begin
    lpp := TPushPop.Create;//建立数据计算对象
    while abds< >'' do
    begin
    c := abds[1];
    if IsCalcFh(c) then//是否运算符
    begin
    lpp.PushFh(c);//保存运算符
    abds := CopyRight(abds,2);
    end
    else
    begin
    if c=')' then
    begin
    Dec(Fghpd);//括号匹配
    abds := CopyRight(abds,2);
    if Fghpd < 0 then
    Raise Exception.Create('括号不配对');
    Result := lpp.CalcValue;
    //返回括号中的子项值,进行下一步计算
    lpp.Free;
    Exit;
    end
    else
    begin
    if c='(' then
    Inc(Fghpd);//做括号层数标识
    lpp.PushValue(BdsYz(abds));//取下一项的值。
    end;
    end;
    end;
    if Fghpd< >0 then
    Raise Exception.Create('括号不配对');
    Result := lpp.CalcValue;//返回最终运算值
    lpp.Free;
    end;

    function TBdsProc.BdsYZ(var abds: String): ValKind;
    begin
    if abds< >'' then
    begin
    if abds[1]='(' then
    begin
    abds := CopyRight(abds,2);
    Result := BdsSs(abds);//递归调用,求括号中的值
    end
    else
    Result := BdsItm(abds);{读一个数据项,
    如果包括函数定义,可以在该方法中定义接口或连接}
    end;
    end;
    若表达式要支持函数功能,只要定义系统支持的函数,
    在取行表达式因子BdsItm中加入连接函数定义即可,如下:
    …..
    else if (c< ='Z') and (c >='A') then
    begin
    bhs := 取出函数名及参数
    Result := … //调用函数处理 (函数定义)
    abds := 下一项
    end
    ….
    < 2 > 数据计算:主要包PushValue,PushFh,
    Calccur分别完成存入数、符号、中间计算
    procedure TPUSHPOP.PushValue(avalue: CDIKind);
    begin
    if fisfh=True then
    Raise Exception.Create('缺少运算符');
    if fisnot then//进行非运算
    begin
    if avalue.id then
    Raise Exception.Create('浮点数不能做非运算');
    avalue.ival := not avalue.ival;
    fisnot := False;
    end;
    if IsLgFh(ffh[flevel]) then//运行逻辑运算
    begin
    value[flevel] := Calclg(value[flevel],
    avalue,ffh[flevel]);
    //与当前值做逻辑运算
    end
    else
    begin
    Inc(flevel);//存数位置指针加1
    value[flevel] := avalue;//存入值
    if flevel >2 then//数据个数达到4,进行中间运算
    Calccur;
    end;
    fisfh := True;//输入符号可见
    end;

    procedure TPUSHPOP.PushFh(afh: Char);
    begin
    if (fisfh=false) then//非运算是一级
    begin
    if (afh='!') and (not fisnot) then//标识非运算
    begin
    fisnot := True;
    Exit;
    end
    else
    Raise Exception.Create('运算符重复');
    End
    Else
    begin
    ffh[flevel] := afh;//存入运算符
    fisfh := False; 输入值可见
    end;
    end;

    procedure TPUSHPOP.Calccur;
    begin
    if IsCcFh(ffh[1]) then//二级运算符
    begin
    value[1] := Calcsj(value[1],value[2],ffh[1]);
    //计算2和3项的值
    ffh[1] := ffh[2];//后序运符和值前移
    value[2] := value[3];
    end
    else//一级运算符
    begin
    value[0] := Calcsj(value[0],value[1],ffh[0]);
    //计算1和2项的值
    value[1] := value[2];{ 后序运符和值前移,
    2和3项的值不计算是为了保持第一个运算符为一级运算符}
    value[2] := value[3];
    ffh[0] := ffh[1];
    ffh[1] := ffh[2];
    end;
    Dec(flevel);//存数位置指针减1
    end;

5,391

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧