CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  语言基础/算法/系统设计

字符窜转换问题!

楼主huangpeiyan(虾米)2004-12-01 13:53:05 在 Delphi / 语言基础/算法/系统设计 提问

比如规格='3*5'  
  怎样根据此字符窜得到数值15.  
  问题点数:20、回复次数:9Top

1 楼gxgyj(杰克逊)回复于 2004-12-01 13:58:44 得分 5

luke5678(奇异)的  
   
  //MS的解决方案:  
   
  在Win2K下在Delphi中Import   ActiveX Control,选Microsoft   Script   Control 1.0,安装,在应用程序中  
  ScriptControl1.Language:='JavaScript';  
  ShowMessage(ScriptControl1.Eval('1+2+3'));  
   
  //解析实现  
  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[I]   =   '('   then  
                  Inc(L)  
              else   if   mText[I]   =   ')'   then  
                  Inc(R);  
              if   L   =   0   then  
                  nLStr   :=   nLStr   +   mText[I]  
              else   if   L   >   R   then  
                  nCStr   :=   nCStr   +   mText[I]  
              else   B   :=   False;  
          end   else   nRStr   :=   nRStr   +   mText[I];  
      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   :=   Calc(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[I]   =   '-')   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   ['+',   '-'])   then  
                  vText   :=   vText   +   '+_'  
              else   vText   :=   vText   +   mText[I]  
          else   vText   :=   vText   +   mText[I];  
      Result   :=   fCalc(vText);  
  end;   {   Calc   }  
   
  Top

2 楼CloneCenter(复制中心)回复于 2004-12-01 14:00:01 得分 1

强就一个字!Top

3 楼sixgj(轰炸机)回复于 2004-12-01 14:05:30 得分 2

做乘法Top

4 楼XuDunYu(西门吹雪)回复于 2004-12-01 14:06:58 得分 1

这实际上就是计算器的程序,大学课本上都有例子,抄一下不就可以了吗?Top

5 楼tigerii(tigerii)回复于 2004-12-01 14:07:14 得分 1

please   refer   to   compile   technologyTop

6 楼ksaiy(阳光总在风雨后)回复于 2004-12-01 18:52:22 得分 5

function   PartitionString(StrV,PrtSymbol:   string):   TStringList;  
  var  
      iTemp:   integer;  
  begin  
      result   :=   TStringList.Create;  
      iTemp   :=   pos(PrtSymbol,StrV);  
      while   iTemp>0   do   begin  
          if   iTemp>1   then   result.Append(copy(StrV,1,iTemp-1));  
          delete(StrV,1,iTemp+length(PrtSymbol)-1);  
          iTemp   :=   pos(PrtSymbol,StrV);  
      end;  
      if   Strv<>''   then   result.Append(StrV);  
  end;  
   
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
      Str:TStrings;  
      a,b,c:integer;  
  begin  
      Str:=PartitionString('3*5','*');  
      a:=StrToInt(Str[0]);  
      b:=StrToInt(Str[1]);  
      c:=a*b;  
      ShowMessage(IntToStr(C));  
  end;  
   
  其它符号你按照这个提取和修改就可以了。Top

7 楼zzlingaaa(小舟)回复于 2004-12-01 19:04:44 得分 5

{{{{{转转转转转转转转转转转转转转转转转转转转}}}}}  
   
  开发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;  
   
  Top

8 楼huangpeiyan(虾米)回复于 2004-12-02 08:38:05 得分 0

呵,我是这样子:  
  adodataset.close;  
  try  
      adodataset.command:='select   '+dataset.fieldbyname('规格').value;  
      adodataset.open;  
  except;  
  end;  
  if   adodataset.active   then  
      case   adodataset.fields[0].datatype   of  
          ftSmallint,ftInteger,ftWord,ftAutoInc,ftFloat,ftCurrency,ftbcd:  
              dataset.fieldbyname('数量').value:=adodataset.fields[0].value;  
      end;  
  如果是查询语句.就先建个字段.把规格转换过来.Top

9 楼huangpeiyan(虾米)回复于 2004-12-02 08:49:02 得分 0

求md5的加密方法.我获取用户网卡MAC.作为注册信息.用MD5将网卡MAC地址加密作为注册码.不知各位有没有源代码借鉴.Top

相关问题

  • 字符转换
  • 字符转换
  • 字符转换
  • 字符转换
  • 字符转换
  • 字符转换?
  • 字符转换
  • 字符转换????
  • 字符串转换
  • 宽字符转换

关键词

  • 函数
  • 括号
  • 字符
  • abds
  • 表达式
  • flevel
  • mtext
  • 运算
  • 运算符
  • vtext

得分解答快速导航

  • 帖主:huangpeiyan
  • gxgyj
  • CloneCenter
  • sixgj
  • XuDunYu
  • tigerii
  • ksaiy
  • zzlingaaa

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo