zoukankan      html  css  js  c++  java
  • 表达式求值-中缀表达式-后缀表达式

    结合性:当优先级相同时,看结合性,若是从左到右结合就是先算左边的运算符,从右到左就是先算右边的运算符。

    优先级:谁优先级别高谁先运算

    结合性列子:如a*b/c%d/e  因为运算符都是自左向右结合的所以 运算顺序为     ((((a*b)/c)%d)/e )

    优先级:a/b-c+d*e-a*c     ->     ((((a/b)-c)+(d*e))-(a*c))

    (人习惯用)中缀表达式:二元运算符放在2个操作数的中间,书写表达式的标准方式是中缀表达式

    (编译器用)后缀表达式:使用的是无括号的表达式

    如  

    中缀表达式          后缀表达式

    2+3*4            234*+

    a*b+5            ab*5+

    (1+2)*7           12+7*   

    a/b*c            ab/c* 

    ((a/(b-c+d))*(e-a)*c      abc-d+/ea-*c*  

    a/b-c+d*e-a*c        ab/c-de*+ac*-  

    中缀表达式到后缀表达式的转换(手工算法):

    1.给每个表达式加上括号

    2.将移动每个二元运算符,将其放在与其相应括号的右括号处 

    3.删除所有括号

    如: 中缀表达式为:a/b-c+d*e-a*c

    执行第一步:((((a/b)-c)+(d*e))-(a*c))

    执行第二步:((((ab/)c-)(de*)+)(ac*)-) 

    执行第三部:ab/c-de*+ac*-

    后缀表达式为:ab/c-de*+ac*-

    手工算法:计算机执行效率低,因为需要2遍扫描,第一遍扫描加括号,第二遍扫描移动运算符

    计算机算法:

    准备一个栈,操作数立即入栈,算法判断优先级后入栈,优先级高的先入栈

    即遇到操作数操作数就入栈,遇到算符先考虑优先级高的入栈。

    中缀表达式转换为后缀表达式函数

     1 #include<stdio.h>
     2 
     3 #define MAX_STACK_SIZE 100        //栈长度 
     4 #define MAX_EXPR_SIZE 100        //最大表达式长度 
     5 
     6 
     7 typedef enum{
     8     lparen,rparen,plus,minus,times,divide,mod,eos,operand
     9 } precedence;         //运算符定义 ()+-*、% 错误 运算数 
    10 
    11 precedence stack[MAX_STACK_SIZE];
    12 static int isp[]={0,19,12,12,13,13,13,0};//()+-*/%eos的栈内优先级 
    13 static int icp[]={20,19,12,12,13,13,13,0};//()+-*/%eos的引入            优先级
    14 int stack[MAX_STACK_SIZE];
    15 int expr[MAX_EXPR_SIZE];    //输入字符串 
    16 
    17 void postfix(void)
    18 {
    19     /*
    20     中缀式转为后缀式 
    21     */
    22     char symbol;
    23     precedence token;
    24     int n=0;
    25     int top=0;
    26     stack[0]=eos;
    27     for(token =get_token(symbol,&n); token!=eos;  token =get_token(symbol,&n)){
    28         if(token==operand)                    //当时运算符直接输出 
    29             printf("%c");
    30         else if(token==rparen){                //有括号的情景,当遇到右括号时,一直出栈到栈顶是左括号 
    31             while(stack[top]!=lparen)
    32                 printf(delete(&top));
    33             delete(&top);
    34         }
    35         else{
    36             while(isp[stack[top]]>=icp[token])//比较优先级
    37                 printf(delete(&top));
    38             add(&top,&token);
    39         }     
    40     }
    41     while((token=delete(&top))!=eos)
    42         prit_token(token);
    43     printf("
    ");
    44 
    45  } 

    后缀式求值函数

     1 void postfix(void)
     2 {
     3     /*
     4     中缀式转为后缀式 
     5     */
     6     char symbol;
     7     precedence token;
     8     int n=0;
     9     int top=0;
    10     stack[0]=eos;
    11     for(token =get_token(symbol,&n); token!=eos;  token =get_token(symbol,&n)){
    12         if(token==operand)                    //当时运算符直接输出 
    13             printf("%c");
    14         else if(token==rparen){                //有括号的情景,当遇到右括号时,一直出栈到栈顶是左括号 
    15             while(stack[top]!=lparen)
    16                 printf(delete(&top));
    17             delete(&top);
    18         }
    19         else{
    20             while(isp[stack[top]]>=icp[token])//比较优先级
    21                 printf(delete(&top));
    22             add(&top,&token);
    23         }     
    24     }
    25     while((token=delete(&top))!=eos)
    26         prit_token(token);
    27     printf("
    ");
    28 
    29  } 

    获取当前字符串的字符:

     1 precedence get_token(char *symbol,int *n)
     2 {
     3     /*
     4         从输入字符串取出一个标记符号的函数 
     5         得到下一个字符给symbol,判断后返回字符相应的值 
     6     */
     7     *symbol=expr[(*n)++];
     8     switch(*symbol){
     9         case '(': return lparen;
    10         case ')': return rparen;
    11         case '+': return plus;
    12         case '-': return minus;
    13         case '/': return divide;
    14         case '*': return times;
    15         case '%': return mod;    // 
    16         case ' ': return eos;    //eos结束符号  
    17         default : return operand;    //没有错误检查,默认是操作数 
    18     }
    19     
    20 }

     precedence stackp[MAX_STACK_SIZE];

    int stack[MAX_STACK_SIZE];

    这2个栈的实现参考前面的简单栈的实现

  • 相关阅读:
    最长公共前缀
    无重复字符的最长子串
    文章采集代码
    网络验证常见的攻击方式与防御手段
    初创公司如何避免服务器被攻击
    拒绝ssh远程暴力破解
    我公司开了7年,靠的就是这套顶级销售打法撑下来!
    顶级销售的十个习惯,轻松签下百万千万合同!(值得背下来)
    顶级销售高手总结的 9 个方面
    一位顶级销售高手总结的“销售心得”!
  • 原文地址:https://www.cnblogs.com/hysz/p/7196832.html
Copyright © 2011-2022 走看看