如何实现:
(a+b)*c*(d+e)
用程序分解为
a*c*d+a*c*e+b*c*d+b*c*e
其中a,..,e是字符串

解决方案 »

  1.   

    不明白.
    呵呵呵呵~~
    定义F,G
    F:=a+b
    g:=d+e
      

  2.   

    这是一个解释器的模型,
    其中:a,b,..,c  等是不定的字符串,
    但是不会包括"+","*","(",")"
    运算符为"+","*",优先级"*">"+"我没学过delphi,
    准备用堆栈实现
    正在写写好后会把代码贴出来的!!!
    只是希望那位有更好的实现,贴出来共享
      

  3.   

    应该是公式解析吧用两个堆栈实现,一个存操作数,称之为a,一个存操作符,称之为b依次读取表达式内容,如果是操作数,则进a,如果是操作符,则判断其与b中最顶端的优先级,优先级高的连同a中最顶端值一起追加到新字符串c中,否则进b依次进行,即可c就是结果
      

  4.   

    分成三步不就得了,
    f := a+b;
    g := d+e;
    f*c*g;
    再把三个相乘,不就可以了,何必非得要一步
      

  5.   

    Gfire(风之蓝歌) ( ):要是
    ((a+b)*c+d)*e+f
    呢--------------------------我想到的方法是,用递归(分析语法)加动态的多维结构(存储多项式)实现。可是对delphi不熟,希望各位帮忙。
      

  6.   

    2个递归函数一个用来分离基本数字和符号。(两个栈)另一个对两个栈进行合并和分解。
    说就容易,做是挺难的。估计至少用两天工作日。(1天写程序,1天测试和修复bug)
      

  7.   

    刚毕业,学DELPHI一个月,大专,没有学过编译原理,看了下题目,可以实现的方法很多,
    随便写了个,请多指教。
    function GetResult(source :string) :string;  //主函数
    var
        iPos :integer;
        a,b :string;
        function AddSign(b :string) :string;
        var
            iPos :integer;
        begin
            iPos := pos('(',b);
            if iPos = 0 then
            begin
                b := '(' + b;
            end;
            iPos := pos(')',b);
            if iPos = 0 then
            begin
                b := b + ')';
            end;
            result := b;
        end;
        function PutoffSign(b :string) :string; //去掉符号 "("和")";
        var
            iPos :integer;
        begin
            iPos := pos('(',b);
            if iPos <> 0 then
            begin
                delete(b,iPos,1);
            end;
            iPos := pos(')',b);
            if iPos <> 0 then
            begin
                delete(b,iPos,1);
            end;
            result := b;
        end;
        function GetSecondSignPos(b :string) :integer;  //获得第二个符号"("
        var
            iPos :integer;
            PosA :integer;
        begin
            result := -1;
            delete(b,1,1);
            iPos := pos('(',b);
            if iPos= 0 then exit;
            result := iPos +1;
        end;
        function GetMulty(source :string) :string;  //基本运算单元 模型 y := (a + b)*( c + d)
        var
            i ,j :integer;
            a,b :TstringList;
            iPos :integer;
            function GetCell(temp :string) :TstringList;
            var
                iPos :integer;
            begin
                Result := Tstringlist.Create;
                iPos := pos('(',temp);
                if iPos <>0 then
                begin
                    delete(temp,iPos,1);
                end;
                iPos := pos(')',temp);
                if iPos <> 0 then
                begin
                    delete(temp,iPos,1);
                end;
                while(true)do
                begin
                    iPos := pos('+',temp);
                    if iPos = 0 then
                    begin
                        Result.Add(temp);
                        break;
                    end else
                    begin
                        Result.Add(copy(Temp,1,iPos-1));
                        Delete(temp,1,iPos);
                    end;
                end;
            end;
        begin
            iPos := GetSecondSignPos(source);
            if iPos = -1 then
            begin
                result := source;
                exit;
            end;
            a := GetCell(copy(source,1,iPos-2));
            delete(source,1,iPos-1);
            b := GetCell(source);
            for i := 0 to a.Count -1 do
            begin
                for j := 0 to b.Count -1 do
                begin
                    if result = '' then
                    begin
                        result := a.Strings[i]+'*'+b.Strings[j];
                    end else
                    begin
                        result := result +' + '+ a.Strings[i]+'*'+b.Strings[j] ;
                    end;
                end;
            end;
            a.Free;
            b.Free;
        end;begin
        //先解析
        a := '';
        while(true)do
        begin
            iPos := pos('*',source);
            if iPos = 0 then
            begin
                a := a + Addsign(source);
                break;
            end else
            begin
                b := copy(source,1,iPos-1);
                a := a + Addsign(b) + '*';
                Delete(source,1,iPos);
            end;
        end;
        source := a;    while(true)do
        begin
            iPos := GetSecondSignPos(source);
            if iPos = -1 then
            begin
                source := PutoffSign(source);
                break;
            end else
            begin
                a := Copy(source,1,iPos-1);
                delete(source,1,iPos-1);
                iPos := GetSecondSignPos(source);
                if iPos = -1 then
                begin
                    source := GetMulty(a+source);
                end else
                begin
                    b := copy(source,1,iPos-2);
                    delete(source,1,iPos-1);
                    source := AddSign(GetMulty(a+b))+'*'+source;
                end;
            end;
        end;
        result := source;
    end;procedure TForm1.Button1Click(Sender: TObject);  //调用方法
    begin
        Edit2.Text := GetResult(Edit1.Text);
    end;
      

  8.   

    多谢 ccc0808xx(加加)
    你的算法可以实现,我一定加分给你想问一下,还有别的实现吗?
    栈的,或是树的遍历我会另开贴给分的
      

  9.   


     ------ ccc0808xx(加加)
    你的算法还有点问题

    a*(b+c)*d+e
      

  10.   

    其实实现的原理都是一样,不过栈的维护我就难得写了,所以就用Tstringlist来实现。
    算法是基于你最初给的格式,其他的格式的解析没有打算去写,实现思路也一样,(一)
    格式标准化(二)找出关键字(三)将格式按照栈解吸。曾经用汇编写了个,所以栈比较好考虑。
      我猜你多半是想用它作一个解析器吧!不过我建议你使用现在有的成熟的控件。我用的脚本
    解析器都是用的人家的控件,两个字:方便。如果需要,发邮箱到我QQ47128653,免费送!
      你的第二个问题,非标准格式的解析,等我有空了 用栈帮你写个!
      

  11.   

    这个问题原理不难,没有必要扯上太多的编译原理。我觉得直接解析成二叉树,然后遍历,这样比较简单。
    不懂 Delphi, 我用java写过简单的表达式的解析,希望对楼主有所帮助
    http://dev.csdn.net/develop/article/20/20719.shtm
    看其中 “面向对象的java实现”里面的类设计。使用二叉树,因为+-*/都是二元运算,a*b*c 其实是(a*b)*c 的简写,a-b+c其实是(a-b)+c的简写,绝不会等于a-(b+c)从字符串解析成二叉树要用栈,编译原理里面有详细的介绍。二叉树每个节点是一个 Expression ,每个 Expression 包含左子节点,运算符,右子节点。遍历二叉树的时候,对每一个节点 Expression,依次比较
    1、 本节点运算符和左子节点运算符的优先级
    2、 本节点运算符和右子节点运算符的优先级
    如果本节点运算符优先级高于子节点(*/优先级大于+-),就调整。注意纯数(对应上面java设计中的Nmbuer类)的运算符优先级最高。举例如下:
    表达式:(a-b)*(c+d)
    解析为
             *
       -          +
     a   b      c   d
    遍历到*代表的那个节点时,比较如下:
    1、 *和-比较,需要调整。所以调整为:
             -
       *          *
     a   +      b   +
    上面+这个节点复制了一份,变成了两个。这个节点复制是深拷贝,其子节点都需要复制。调整之后,本节点要重新进行1、2两步比较。最后直接使用根节点的 toString() (这也是一个递归方法) 就能显示出所要的结果。
      

  12.   

    多谢 sliant() ( )
    说得很清楚了
    那位高人帮忙实现一下,练练手。---------------------------------------
    而我的方法是用一个递归直接解析成

     {A,B,C}
     {D,E}
     {F,G,H }  
    }
    这也是我要的最终形式
      

  13.   

    这个不难,如果看数学基础牢
    那么
    1,解线性方程因式分解
    比如:
    输入:"a^2 - 2*a*b + b^2"
    输出:"(a-b)*(a-b)"提示:好好回家看看线性代数的书哦。 2,级数:输入:e ^ x
    输出:∑ x ^ n / n!哈哈,第一题可能答出,第二题你要苦练10年哦!!!
      

  14.   

    1.用栈
      原理上面已经有人说了,估计也没什么别的方法
    2.用树
      上面也有人说了.
    3.用字符替换
      这个用的资源比较少,用循环检查表达式的')'找到后就找他左边的最近的'(',然后计算里面的结果,将得到的结果替换掉括号之间的内容,如此循环.无论哪种方法,递归都是必须的.原理大同小异.第三种方法实现代码
    http://borland.mblogger.cn/lw549/posts/808.aspx
      

  15.   

    我的方法是用一个递归直接解析成

     {A,B,C}
     {D,E}
     {F,G,H }  
    }------
    type
      TRuleList=class(TStringList)
      private
        //确定需要添加项的列数,例:(a+b)*c 中添加 c 时为2 。
        addcount:integer;
      public
        Constructor Create();
        procedure addColumn(); //加列
        procedure addItem(const item:string); //为account列加新行
        procedure addList(const childlist:TRuleList); //加新表
        function getRule():string;
        Destructor Destroy();override;
      end;-----------
    //主函数
    function getResult(const source:string):string;
    var
      ipos:integer;   //原始字符串遍历下标
      bracketcount:integer; //括号记数
      wordflag:0..2; //0-未开始读词;1-已开始读词;2-括号结束
      aword:string; //词
      //err:string; //出错信息
      rulelist:TRuleList; //规则 function getRule(const source:string):TRuleList; //解析函数
      var
       rlist,childlist:TRuleList;
      begin
       result:=nil;
       rlist:=TRuleList.Create();
       try
        while ipos<=length(source) do
         begin
          case source[ipos] of
           AnsiChar('*'):
           begin
            if wordflag=0 then
             begin
               raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 * 号附近');
             end;
           if wordflag=1 then
           begin
             rlist.addItem(aword);
           end;
           wordflag:=0;
           aword:='';
           ipos:=ipos+1;
          end;  //'*'
        AnsiChar('+'):
          begin
           if wordflag=0 then
            begin
             raise Exception.Create('语法错误: 第'+inttostr(ipos)+'字节 + 号附近');
            end;
           if wordflag=1 then
             rlist.addItem(aword);
           rlist.addColumn();
           wordflag:=0;
           aword:='';
           ipos:=ipos+1;
          end;  // '+'
         AnsiChar('('):
          begin
           bracketcount:=bracketcount+1;
           ipos:=ipos+1;
           if wordflag=1 then
            begin
             rlist.addItem(aword);
             wordflag:=0;
             aword:='';
            end;
           childlist:=getRule(source);//递归
           if childlist<>nil then
            begin
               rlist.addlist(childlist);
               childlist.Free();
            end
            else
            begin
               break;
            end
           end; // '('
          AnsiChar(')'):
           begin
            bracketcount:=bracketcount-1;
            ipos:=ipos+1;
            if(bracketcount<0) then
             begin
              raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,括号不匹配');
             end;
            if wordflag=1 then
             begin
              rlist.addItem(aword);
              wordflag:=2;
              aword:='';
            end;
            if wordflag=0 then
             begin
              raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近');
             end;
            if rlist.Count=0 then
             begin
              raise Exception.Create('语法错误: 第'+inttostr(ipos-1)+'字节 ) 号附近,空括号');
             end;
            result:=rlist;
            break;
           end;  // ')'
           else
           begin
            aword:=aword+source[ipos];
            wordflag:=1;
            ipos:=ipos+1;
           end; //else
       end; //case
      end;   //while
      //showMessage(inttostr(bracketcount)+'  '+rlist.getRule()); //调试信息
      if (bracketcount<>0) and (ipos>=length(source)) then
       begin
          raise Exception.Create('语法错误:结束时括号不匹配');
       end;  if (bracketcount=0) and (ipos>length(source)) then  //遍历完成,正常返回
       begin
          if wordflag=1 then
          begin
           rlist.addItem(aword);
           wordflag:=0;
          end;
          result:=rlist;
       end;
         //else 未完成(出错,或是递归返回)  except
       on Exception do
        begin
         if rlist<>nil then
             begin
               rlist.Free();
             end;
         raise; //重发
        end;
      end;//except
     end; //function getRulebegin
      ipos:=1;
      rulelist:=nil;
      wordflag:=0;
      aword:='';
      bracketcount:=0;
      try
       rulelist:=getRule(source); //获得规则
       if rulelist<>nil then
       begin
        result:=rulelist.getRule();
        rulelist.Free();
       end
      except
       on e:Exception do
         showMessage(e.Message);
      end;
    end; //function getResult
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Edit2.Text:=getResult(Edit1.Text);
    end;
      

  16.   

    看俺的!
    if str =‘(a+b)*c*(d+e)’then 
     str:='a*c*d+a*c*e+b*c*d+b*c*e'
    ;哈哈,搞笑一下