文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>表达式求值(C/Delphi)

表达式求值(C/Delphi)

时间:2008-11-19  来源:hzg134679

#include      <windows.h>
#include      <stdio.h>
#include      <stdlib.h>
#include      <malloc.h>
#define    TRUE          1
#define    FALSE         0
#define    OK            1
#define    ERROR         0
#define    INFEASIBLE -1
#define    OVERFLOW     -2
#define    SYMBOL        1
#define    VALUE         2
typedef struct BiTNode
{
      char      symbol;                       //符号
      double    value;                        //数值
      int       type;                         //类型
      struct    BiTNode *lchild, *rchild;     //左右孩子指针
}BiTNode, *BiTree;
char symbol[4][4]={{'>', '>', '<', '<'},        //符号优先级
                     {'>', '>', '<', '<'},
                     {'>', '>', '>', '>'},
                     {'>', '>', '>', '>'}};
                  
int sym2num(char s)                             //返回符号对应优先级矩阵位置
{
      switch(s)
      {
          case '+':     return 0;     break;
          case '-':     return 1;     break;
          case '*':     return 2;     break;
          case '/':     return 3;     break;
      }
}
char Precede(char a, char b)                    //返回符号优先级
{
      return(symbol[sym2num(a)][sym2num(b)]);
}
int InitBiTNode(BiTNode **node)                 //树结点的初始化
{
      (*node) = (BiTNode *)malloc(sizeof(BiTNode));
      if(!(*node))
      {  
          printf("内存申请失败!\n");
          system("PAUSE");
          exit(ERROR);
      }    
      (*node)->lchild = NULL;
      (*node)->rchild = NULL;
      return OK;
}
int IsSymbol(char c)                 //判断是否为符号
{
      if(c == '+' || c == '-' || c == '*' || c == '/')
          return TRUE;
      else
          return FALSE;
}
int IsNumber(char c)                  //判断是否为数字
{
      if(c >= '0' && c <= '9')
          return TRUE;
      else
          return FALSE;
}
double char2value(int *i, char *p)    //把字符型的数值转化成双浮点型    
{  
char *c = p;
int flag = 0,number;
double quan, ans = 0;
while(1)
{
    if(*c == '.')
    {
     flag++;
     number = c - p;
    }
    if(*c != '.' && !IsNumber(*c))
     break;
    c++;
}
*i += c - p;
if(flag == 0)
{
    for(quan = 1, c--; c >= p; c--, quan*=10)
    ans += (*c-'1'+1) * quan;
}
else
{
    for(c--, quan = pow(10, number - (c - p)); c >= p; c--)
    {
     if(*c == '.')
      continue;
     else
     {
      ans += (*c - '1' + 1) * quan;
      quan *= 10;
     }
    }
}
return(ans);
}
int GetValue(BiTree *VTree, int *i, char *Exp)       //得到表达式中的数值
{
      int j, brackets = 0;          //左括号减右括号的个数
      int flag = 0;                 //左右括号相等标志
      char ChildExp[100];           //子表达式
      if(Exp[(*i)] == '(')
      {
          (*i)++;
          brackets++;
          for(j = 0; Exp[(*i)] != '\0'; (*i)++, j++)
          {
              if(Exp[(*i)] == '(')
                  brackets++;       //左括号加1
              if(Exp[(*i)] == ')')
                  brackets--;       //右括号减1
              if(brackets == 0)
              {
                  flag++;           //左右括号相等跳出循环
                  break;
              }
              ChildExp[j] = Exp[(*i)];    //表达式括号中的内容给子表达式
          }
          if(flag == 0)
          {
              printf("括号配对语法错误!\n");
              system("PAUSE");
              exit(ERROR);         //表达式中没有找到匹配括号
          }
          ChildExp[j] = '\0';
          (*i)++;
          exp2tree(VTree, ChildExp);      //求子表达式树型结构
      }
      else
      {
          if(IsNumber(Exp[(*i)]))      
          {
              InitBiTNode(VTree);         //数值类型结点
              (*VTree)->type = VALUE;
              (*VTree)->value = char2value(i, Exp + (*i));
          }
          else
          {
              printf("符号位置语法错误!\n");
              system("PAUSE");
              exit(ERROR);                //符号后跟数字
          }
      }
}
int GetSymbol(BiTree *STree, int *i, char *Exp)
{
      if(IsSymbol(Exp[(*i)]) == TRUE)
      {
          InitBiTNode(STree);            //符号类型结点
          (*STree)->type = SYMBOL;
          (*STree)->symbol = Exp[(*i)];
          (*i)++;
          return OK;
      }
      else if(Exp[(*i)] == '\0')
      {
          return ERROR;                  //结束标志返回失败
      }
      else
      {
          printf("数字后跟符号!\n");
          system("PAUSE");               //非符号非结束标志  
          exit(ERROR);                   //数字后跟符号
      }
}

int exp2tree(BiTree *Tree, char *Exp)
{
      int i = 0, flag = 0;               //正常结束标志
      BiTree ValTree;                    //数值结点指针
      BiTree SymTree;                    //符号结点指针
      BiTree CurTree;                    //当前结点指针
      //预先存一个数值一个符号结点到树型结构 便于后面的比较
      GetValue(&ValTree, &i, Exp);    
      if(GetSymbol(&SymTree, &i, Exp) == OK)
      {
          SymTree->lchild = ValTree;
          *Tree = SymTree;
          CurTree = *Tree;
      }
      else
      {
          (*Tree) = ValTree;             //如果只有一个数值直接给根结点
          return OK;
      }
      for( ; Exp[i] != '\0'; )
      {
          GetValue(&ValTree, &i, Exp);
          if(GetSymbol(&SymTree, &i, Exp) == OK)
          {
              //与根结点符号比较优先级
              if(Precede((*Tree)->symbol, SymTree->symbol) == '>')
              {  
                  //根结点符号优先于新插入符号
                  CurTree->rchild = ValTree;    //数值结点作为当前结点右子树            
                  CurTree = SymTree;            //当前结点改为字符结点
                  CurTree->lchild = *Tree;      //根结点作为当前结点左子树
                  *Tree = SymTree;              //根结点改为字符结点
              }
              else
              {
                  //根结点符号后于新插入符号
                  SymTree->lchild = ValTree;    //数值结点作为字符结点右子树
                  CurTree->rchild = SymTree;    //字符结点作为当前结点右子树
                  CurTree = CurTree->rchild;    //当前结点改为当前结点右子树
              }
          }
          else
          {
              CurTree->rchild = ValTree;      //数值结点作为当前结点右子树
              flag++;                         //在数值后没有接受到符号
              return OK;                      //正常结束
          }
      }
      if(flag == 0)
      {
          printf("符号后缺数值!\n");
          system("PAUSE");
          exit(ERROR);                        //没有正常结束
      }
}

//计算一个结点的值.
double EvaluateExpression(BiTree Tree)
{
      if(Tree->type != VALUE)             //如果根结点不为数值类型
      {
          Tree->type = VALUE;             //以根结点为树型结构求值
          switch(Tree->symbol)
          {
              case '+':  
                  Tree->value = EvaluateExpression(Tree->lchild) + EvaluateExpression(Tree->rchild);
                  break;
              case '-':
                  Tree->value = EvaluateExpression(Tree->lchild) - EvaluateExpression(Tree->rchild);
                  break;
              case '*':  
                  Tree->value = EvaluateExpression(Tree->lchild) * EvaluateExpression(Tree->rchild);
                  break;
              case '/':  
                  Tree->value = EvaluateExpression(Tree->lchild) / EvaluateExpression(Tree->rchild);
                  break;
          }
          free(Tree->lchild);             //释放左子树
          free(Tree->rchild);             //释放右子树
      }
      return(Tree->value);                //返回根结点数值
}

int main(int argc, char *argv[])
{
      BiTree T;
      T = NULL;                           //初始化根结点
      char expression[100];               //初始化表达式
      printf("请输入表达式:");
      scanf("%s", expression);            //输入表达式
      exp2tree(&T, expression);           //将表达式转为树型结构
      printf("输出的结果是:%f\n", EvaluateExpression(T));
                                        //对树型结构求解
      system("PAUSE");
}

//后面下载的.
//后缀表达式求值
int postexpression(char *exp)
{
   stack<int> *opnd=new(stack<int>);//操作数栈
   char ch=*exp;
   int x=0,y,z,flag=FALSE;
   int result;
   while(ch!='#')
   {
       if(!Operator(ch))              //如果当前字符不是运算符
       {
           if(ch!=' ')
           {
             x=x*10+(int)(ch)-48;     //计算操作数
             flag=TRUE;
           }
           else
           {
             if(flag)opnd->push(x);   //操作数入栈
             x=0;
             flag=FALSE;
           }
       }
       else                //当前字符为运算符,两个操作数出栈,计算并将结果入栈
       {
           x=opnd->pop();
           y=opnd->pop();
           z=calc(y,ch,x);
           opnd->push(z);
       }
       ch=*(++exp);          //取下一字符
   }
   result=opnd->pop();
   return(result);
}

//初始化公式
function initexp(const  exp:string):Boolean;
var
     tmp,i,j:integer;
begin
      i:=1;
      j:=1;//将零位备用做其他用途
      tmp:=0;//记录前一个符号的位置
      while i<=Length(exp) do
      begin
           if isfh( exp[i] ) then
           begin
               if i-tmp>1 then
               begin
                   arrayexp[j].isdata:=true;  //记录数字
                   arrayexp[j].data:=StrToInt(Copy(Exp,tmp+1,i-tmp-1));
                   Inc(j);
               end;
               arrayexp[j].isdata:=False;  //记录符号
               arrayexp[j].symbol:=Exp[i];
               Inc(j);
               tmp:=i; //暂存符号
           end;
           Inc(i);
      end;
end;

//除去括号
function delbrk:Boolean;
var i,j:integer;//i:左括号  j:右括号  //最好先初始化每个数组的优先级标志
begin
   i:=1;
   j:=0;
   while arrayexp[i].symbol<>'#' do
   begin
        if arrayexp[i].symbol='(' then
        begin
             j:=j+10;//优先级
             arrayexp[i].isdata:=0;//空符号
        end;
        if arrayexp[i].symbol=')' then
        begin
             j:=j-10;//优先级
             arrayexp[i].isdata:=0;//空符号
        end;
        if arrayexp[i].isdata=2 then
           arrayexp[i].priv:=arrayexp[i].priv+j;
        Inc(i);
   end;
end;

//测试文档
procedure TForm1.Button1Click(Sender: TObject);
var x:Word;
    s:string;
    i:Integer;
begin
  {s:='+';
  if s='+' then
  ShowMessage(s); }
  //x:=Integer('-');
  //ShowMessage(Char(x));
  //Edit3.Text:= string(Edit1.Text[1]);
  //Edit3.Text:= string(Precede(Edit1.Text[1],Edit2.Text[1]));
  s:='(18-8)*(9-(10-2))*2+5#';
  initexp(s);  //初始化
  delbrk;      //除去括号
  for i:=1 to Length(arrayexp) do
  begin
    if arrayexp[i].isdata=1 then
      ShowMessage('数字:'+inttostr(arrayexp[i].data));
    if arrayexp[i].isdata=2 then
     ShowMessage('符号:'+arrayexp[i].symbol+'  符号优先级是:'+inttostr(arrayexp[i].priv));
  end;
end;

//关键记录,关于符号和数字内容
type
  aryexp=packed record
  priv:ShortInt;//优先级 ,先设计最简单的     //+ -  1   * /   2
  isdata:Integer;//1:数字  2:符号  3:空.
  case Boolean of
       true:  (data:LongInt);
       False:   (symbol:char);
end;  

//取得下一个可用节点   //dir   0 left减去  1 right 加上
function getindex(i,dir:Integer):Integer;
begin
    if dir=0 then
    begin
        dec(i);
        while arrayexp[i].isdata=3 do
           dec(i);
        Result:=i;
    end;
    if dir=1 then
    begin
        inc(i);
        while arrayexp[i].isdata=3 do
           inc(i);
        Result:=i;
    end;
end;

//查找根结点
function searchrootnode(highINT,LowINT:integer):integer;
var i:Integer;
     MINpriv:integer;
begin
    MINpriv:=100;
    for i:=highINT downto LowINT do
    begin
         if (arrayexp[i].isdata=2) and (arrayexp[i].priv<MINpriv) then
         begin
            MINpriv:=arrayexp[i].priv;
            Result:=i;
         end;
    end;
    if MINpriv=100 then
    Result:=-1;
end;

//建立二叉树.
//递归过程,完全不用DELPHI只带的树功能.TREEVIEW和LIST,自己管理.
//delphi初始化的时候将INTEGER类型初始化为空,Pointer为nil.
function huzgtree(highINT,LowINT:integer):PTwotree;
var  i:Integer;
     root:PTwotree;
begin
      New(root);
      if highINT>LowINT then
      begin
        i:=searchrootnode(highINT,LowINT);
        root^.NodeExp.symbol:=arrayexp[i].symbol;
      end
      else
      begin
        i:=highINT;
        root^.NodeExp.data:=arrayexp[i].data;
        //huzgtree:=root;
        //Exit;
      end;
      if getindex(i,0)>=LowINT then
      root^.lchild:=huzgtree(getindex(i,0),LowINT);
      if getindex(i,1)<=highINT then
      root^.rchild:=huzgtree(highINT,getindex(i,1));
      huzgtree:=root;
end;
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载