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个栈的实现参考前面的简单栈的实现

  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/hysz/p/7196832.html
Copyright © 2011-2022 走看看