• c语言,中缀表达式转后缀表达式并计算


      一、中缀表达式转后缀表达式并计算,后缀表达式字符串形式,数字限定小于10,利用数字栈操作符栈

      1 /*  c语言的中缀表达式转后缀表达式并计算结果
      2 中缀表达式含双目运算符和小括号,数字操作数小于10,    
      3     演示转变及计算过程
      4 */
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <stdbool.h>
      9 #include <math.h>
     10 
     11 /* 操作符栈结构体 */
     12 typedef struct{
     13     char data[85];
     14     int top;
     15 }stack;
     16 
     17 /* 数字栈结构体 */
     18 typedef struct{
     19     int data[85];
     20     int top;
     21 }nstack;
     22 
     23 /* 栈操作函数声明 */
     24 int priority(char);
     25 char pop(stack*);
     26 int npop(nstack*);
     27 int ntop(nstack*);
     28 char top(stack*);
     29 void push(stack*,char);
     30 void npush(nstack*,char);
     31 bool isnumber(char);
     32 bool isempty(stack*);
     33 
     34 int main()
     35 {
     36     int i,j,len,cnt;//字符串下标、长度变量
     37     
     38     stack *st=(stack*)malloc(sizeof(stack)); //操作符栈
     39     nstack *nst=(nstack*)malloc(sizeof(nstack));//数字栈    
     40     st->top=-1;  //操作符栈空
     41     nst->top=-1; //数字栈空
     42     
     43     char str[85];//中缀表达式字符串
     44     char out[85];//后缀表达式字符串
     45     
     46     scanf("%s",str);//读取中缀表达式字符串
     47      
     48     cnt=0;//后缀表达式字符串下标
     49     len=strlen(str);//读取的中缀表达式字符串长度
     50     
     51     /* 1.中缀表达式转后缀表达式 */   //1*(2+3)-4
     52     for(i=0;i<len;i++)
     53     {
     54         /* 从字符串读取的字符为数字,插入到后缀表达式字符串 */
     55         if(isnumber(str[i]))
     56             out[cnt++]=str[i];
     57         else
     58         {
     59             /* 读取的非数字字符是左括号 或者 操作符栈为空,
     60                读取的字符压到操作符栈,
     61                然后去判断字符串是否读完 */
     62             if(str[i]=='('||isempty(st))
     63             {
     64                 push(st,str[i]);
     65                 continue;
     66             }
     67             /* 读取的非数字字符是右括号,判断操作符栈是否为左括号,            
     68             不是左括号把栈顶的操作符插入到后缀表达式字符串并弹出
     69             最后把左括号弹出,然后去判断字符串是否读完*/
     70             if(str[i]==')')
     71             {
     72                 while(top(st)!='(')
     73                 {
     74                     out[cnt++]=top(st);
     75                     pop(st);
     76                 }
     77                 pop(st);
     78                 continue;
     79             }
     80             /* 操作符栈不空且栈顶元素不是左括号
     81             且栈顶元素的优先级大于等于读取的字符优先级
     82             栈顶的操作符插入到后缀表达式字符串并弹出*/
     83             while(!isempty(st)&&top(st)!='('&& priority(str[i])<=priority(top(st)))
     84             {
     85                 out[cnt++]=top(st);
     86                 pop(st);
     87             }
     88             /* 操作符栈空了或栈顶元素为左括号或
     89             栈顶元素的优先级小于读取的字符优先级
     90             读取的字符压到操作符栈 */
     91             push(st,str[i]);
     92         }
     93     }
     94     /* 操作数栈不为空依次弹出插入到后缀表达式字符串 */
     95     while(!isempty(st)){
     96         out[cnt++]=top(st);
     97         pop(st);
     98     }
     99     out[cnt]='';    
    100     /* 打印后缀表达式 */     //1 2 3 + * 4 -
    101     for(i=0;i<cnt;++i)
    102         printf("%c ",out[i]); 
    103     printf("
    ");
    104     
    105     /* 2.根据后缀表达式计算 */     
    106     for(i=0;i<cnt;i++) 
    107     {
    108         /* 从后缀表示字符串读字符,是数字压数字栈,
    109         然后判断字符串是否读完 */
    110         if(isnumber(out[i])){
    111             npush(nst,out[i]); 
    112             continue;
    113         }else if(out[i]=='+'){//数字栈顶元素加到下面元素并弹出栈顶元素
    114             nst->data[nst->top-1]+=ntop(nst);
    115             npop(nst);
    116         }else if(out[i]=='-'){//同理减到下面元素
    117             nst->data[nst->top-1]-=ntop(nst);
    118             npop(nst);
    119         }else if(out[i]=='*'){ //同理乘到下面元素并弹出栈顶元素
    120             nst->data[nst->top-1]*=ntop(nst);
    121             npop(nst);
    122         }else if(out[i]=='/'){ //同理除到下面元素并弹出栈顶元素
    123             nst->data[nst->top-1]/=ntop(nst);
    124             npop(nst);
    125         }else if(out[i]=='^'){//同理幂到下面元素并弹出栈顶元素
    126             nst->data[nst->top-1]=pow(nst->data[nst->top-1],ntop(nst));
    127             npop(nst);
    128         }
    129         for(j=0;j<=nst->top;++j)//一趟后剩余的数字栈遍历打印
    130             printf("%d ",nst->data[j]);
    131         for(j=i+1;j<cnt;++j) //一趟后剩余的后缀表达式字符打印
    132             printf("%c ",out[j]);
    133         printf("
    ");
    134     }
    135     return 0;
    136 }
    137 /* 是否数字函数 */
    138 bool isnumber(char ch){
    139     if(ch>='0'&&ch<='9')
    140         return true;
    141     else
    142         return false;
    143 }
    144 /* 是否栈空函数 */
    145 bool isempty(stack *s){
    146     if(s->top==-1)
    147         return true;
    148     else
    149         return false;
    150 }
    151 /* 压栈函数 */
    152 void push(stack *s,char ch){
    153     s->data[++s->top]=ch;
    154 }
    155 void npush(nstack *s,char ch){
    156     s->data[++s->top]=ch-'0';
    157 }
    158 /* 弹栈函数 */
    159 char pop(stack *s){
    160     return s->data[s->top--];
    161 }
    162 int npop(nstack *s){
    163     return s->data[s->top--];
    164 }
    165 /* 操作符优先级函数 */
    166 int priority(char ch){
    167     if(ch=='(')
    168         return 0;
    169     if(ch=='+'||ch=='-')
    170         return 1;
    171     if(ch=='*'||ch=='/')
    172         return 2;
    173     if(ch=='^')
    174         return 3;
    175     return 0;
    176 }
    177 /* 取栈顶元素函数 */
    178 char top(stack *s){
    179     return s->data[s->top];
    180 }
    181 int ntop(nstack *s){
    182     return s->data[s->top];
    183 }
    字符串形式

      二、中缀表达式转后缀表达式并计算,后缀表达式结构体数组形式,数字可多位,利用数字栈操作符栈

    后缀表达式结构体数组中的联合体既可以存放int类型的数字也可以存放char型操作符,可以判断数组元素的数据类型

      1 /*  c语言的中缀表达式转后缀表达式并计算结果
      2 中缀表达式含双目运算符和小括号,数字操作数可以多位,    
      3     演示转变及计算过程
      4 */
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <stdbool.h>
      9 #include <math.h>
     10 
     11 /* 操作符栈结构体 */
     12 typedef struct{
     13     char data[85];
     14     int top;
     15 }stack;
     16 
     17 /* 数字栈结构体 */
     18 typedef struct{
     19     int data[85];
     20     int top;
     21 }nstack;
     22 
     23 /* 表达式结构体 */
     24 typedef struct {    
     25     short b;//判断类型
     26     union {
     27         int num;
     28         char ch;
     29     }u;        
     30 }EXPRESSION;
     31 
     32 /* 栈操作函数声明 */
     33 int priority(char);
     34 char pop(stack*);
     35 int npop(nstack*);
     36 int ntop(nstack*);
     37 char top(stack*);
     38 void push(stack*,char);
     39 void npush(nstack*,int);//参数int
     40 bool isnumber(char);
     41 bool isempty(stack*);
     42 
     43 int main()
     44 {
     45     int i,j,len,cnt;//字符串下标、长度变量
     46     
     47     stack *st=(stack*)malloc(sizeof(stack)); //操作符栈
     48     nstack *nst=(nstack*)malloc(sizeof(nstack));//数字栈    
     49     st->top=-1;  //操作符栈空
     50     nst->top=-1; //数字栈空
     51     
     52     char str[85];//中缀表达式字符串
     53     EXPRESSION out[85];//后缀表达式结构体数组    
     54     cnt=0;//后缀表达式数组下标
     55     int sum = 0;//累加数字
     56     
     57     scanf("%s",str);//读取中缀表达式字符串 
     58     len=strlen(str);//读取的中缀表达式字符串长度
     59     int flag = 0;//是数字标识
     60     
     61     /* 1.中缀表达式转后缀表达式(用操作符栈) */ 
     62     for(i=0;i<=len;i++)// 100*(2+3)-4   100 2 3 + * 4 -   
     63     {
     64         /* 从字符串读取的字符为数字,插入到后缀表达式结构体数组 */
     65         if(isnumber(str[i])&&i<=len){
     66             sum = sum*10 + str[i] - '0';//累加数字            
     67             flag = 1;//是数字标识
     68             continue;
     69         }
     70         /* 数字进后缀表达式结构体数组的数字 */
     71         if(flag) 
     72         {
     73             out[cnt].b = 1;
     74             out[cnt++].u.num = sum;
     75             flag = 0;
     76             sum = 0;
     77         }                
     78         /* 读取的非数字字符是左括号 或者 操作符栈为空,
     79         读取的字符压到操作符栈,
     80         然后去判断字符串是否读完 */
     81         if(str[i]=='('||isempty(st))
     82         {
     83             push(st,str[i]);
     84             continue;
     85         }
     86         /* 读取的非数字字符是右括号,判断操作符栈是否为左括号,            
     87         不是左括号把栈顶的操作符插入到后缀表达式数组并弹出
     88         最后把左括号弹出,然后去判断字符串是否读完*/
     89         if(str[i]==')')
     90         {
     91             while(top(st)!='(')
     92             {
     93                 out[cnt].b = 2;
     94                 out[cnt].u.ch=top(st); //操作符进后缀表达式数组的字符
     95                 cnt++;
     96                 pop(st);
     97             }
     98             pop(st);
     99             continue;
    100         }
    101         /* 操作符栈不空且栈顶元素不是左括号
    102         且栈顶元素的优先级大于等于读取的字符优先级
    103         栈顶的操作符插入到后缀表达式数组并弹出*/
    104         while(!isempty(st)&&top(st)!='('&& priority(str[i])<=priority(top(st)))
    105         {
    106             out[cnt].b = 2;
    107             out[cnt++].u.ch = top(st);//操作符进后缀表达式数组的字符
    108             pop(st);
    109         }
    110         /* 操作符栈空了或栈顶元素为左括号或
    111         栈顶元素的优先级小于读取的字符优先级
    112         读取的字符压到操作符栈 */
    113         push(st,str[i]);
    114     }
    115     /* 操作符栈不为空依次弹出插入到后缀表达式数组*/
    116     while(!isempty(st)){
    117         out[cnt].b = 2;
    118         out[cnt++].u.ch = top(st);//操作符进后缀表达式数组的字符
    119         pop(st);
    120     }  
    121     /* 打印后缀表达式 */     //100 2 3 + * 4 -   100*(2+3)-4
    122     for(i=0;i<cnt;++i)
    123     {
    124         if(out[i].b==1)
    125             printf("%d ",out[i].u.num);
    126         else printf("%c ",out[i].u.ch);
    127     }
    128     printf("
    ");
    129     
    130     /* 2.根据后缀表达式计算(用操作符栈数字栈) */     
    131     for(i=0;i<cnt;i++) 
    132     {
    133         /* 从后缀表达式结构体数组读取,是数字压数字栈,
    134         然后判断结构体数组是否读完 */
    135         if(out[i].b == 1){
    136             npush(nst,out[i].u.num); 
    137             continue;
    138         }
    139         else if(out[i].u.ch=='+'){//数字栈顶元素加到下面元素并弹出栈顶元素
    140             nst->data[nst->top-1]+=ntop(nst);
    141             npop(nst);            
    142         }else if(out[i].u.ch=='-'){//同理减到下面元素并弹出栈顶元素
    143             nst->data[nst->top-1]-=ntop(nst);
    144             npop(nst);
    145         }else if(out[i].u.ch=='*'){ //同理乘到下面元素并弹出栈顶元素
    146             nst->data[nst->top-1]*=ntop(nst);
    147             npop(nst);
    148         }else if(out[i].u.ch=='/'){ //同理除到下面元素并弹出栈顶元素
    149             nst->data[nst->top-1]/=ntop(nst);
    150             npop(nst);
    151         }else if(out[i].u.ch=='^'){//同理幂到下面元素并弹出栈顶元素
    152             nst->data[nst->top-1]=pow(nst->data[nst->top-1],ntop(nst));
    153             npop(nst);
    154         }
    155         
    156         for(j=0;j<=nst->top;++j)//一趟后剩余的数字栈遍历打印
    157             printf("%d ",nst->data[j]);
    158         for(j=i+1;j<cnt;++j) //一趟后剩余的后缀表达式数字或操作符打印
    159         {
    160             if(out[j].b==1)
    161                 printf("%d ",out[j].u.num);
    162             else printf("%c ",out[j].u.ch);
    163         }          
    164         printf("
    ");
    165     }
    166     return 0;
    167 }
    168 /* 是否数字函数 */
    169 bool isnumber(char ch){
    170     if(ch>='0'&&ch<='9')
    171         return true;
    172     else
    173         return false;
    174 }
    175 /* 是否栈空函数 */
    176 bool isempty(stack *s){
    177     if(s->top==-1)
    178         return true;
    179     else
    180         return false;
    181 }
    182 /* 压栈函数 */
    183 void push(stack *s,char ch){
    184     s->data[++s->top]=ch;
    185 }
    186 //参数int
    187 void npush(nstack *s,int ch){
    188     s->data[++s->top] = ch;
    189 }
    190 /* 弹栈函数 */
    191 char pop(stack *s){
    192     return s->data[s->top--];
    193 }
    194 int npop(nstack *s){
    195     return s->data[s->top--];
    196 }
    197 /* 操作符优先级函数 */
    198 int priority(char ch){
    199     if(ch=='(')
    200         return 0;
    201     if(ch=='+'||ch=='-')
    202         return 1;
    203     if(ch=='*'||ch=='/')
    204         return 2;
    205     if(ch=='^')
    206         return 3;
    207     return 0;
    208 }
    209 /* 取栈顶元素函数 */
    210 char top(stack *s){
    211     return s->data[s->top];
    212 }
    213 int ntop(nstack *s){
    214     return s->data[s->top];
    215 }
    结构体数组形式

      三、中缀表达式转后缀表达式并计算,后缀表达式结构体数组形式,数字可多位,利用数字栈操作符栈

    数字栈、操作符栈使用同一结构体,统一接口

      1 /*  c语言的中缀表达式转后缀表达式并计算结果
      2 中缀表达式含双目运算符和小括号,数字操作数可以多位,    
      3     演示转变及计算过程
      4 */
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <stdbool.h>
      9 #include <math.h>
     10 #define N 256
     11 
     12 /* 栈结构体 */
     13 typedef struct{
     14     short tag; //判断类型
     15     union{         
     16         int* idata;        
     17         char* cdata;
     18     }u;     
     19     int top;
     20 }stack;
     21 
     22 /* 表达式结构体 */
     23 typedef struct {    
     24     short tag;//判断类型
     25     union {
     26         int num;
     27         char ch;
     28     }u;        
     29 }EXPRESSION;
     30 
     31 /* 栈操作函数声明 */
     32 void push(stack*, int);
     33 int pop(stack*);
     34 int top(stack*);
     35 int priority(char);
     36 bool isnumber(char);
     37 bool isempty(stack*);
     38 
     39 int main()
     40 {
     41     int i,j,len,cnt;//字符串下标、长度变量
     42     
     43     stack istack, cstack;//数字栈 操作符栈
     44     
     45     istack.tag = 1;
     46     istack.u.idata = (int*)malloc(sizeof(int)*N);
     47     istack.top = -1;  //操作符栈空
     48     
     49     cstack.tag = 0;  
     50     cstack.u.cdata = (char*)malloc(sizeof(char)*N);    
     51     cstack.top = -1; //数字栈空
     52     
     53     char str[N];//中缀表达式字符串
     54     EXPRESSION out[N];//后缀表达式结构体数组    
     55     cnt = 0;//后缀表达式数组下标
     56     int sum = 0;//累加数字
     57     
     58     scanf("%s",str);//读取中缀表达式字符串 
     59     len = strlen(str);//读取的中缀表达式字符串长度
     60     int flag = 0;//是数字标识
     61     
     62     /* 1.中缀表达式转后缀表达式(用操作符栈) */ 
     63     for(i=0; i<=len; i++)// 100*(2+3)-4   100 2 3 + * 4 -   
     64     {
     65         /* 从字符串读取的字符为数字,插入到后缀表达式结构体数组 */
     66         if(isnumber(str[i])){
     67             sum = sum*10 + str[i] - '0';//累加数字            
     68             flag = 1;//是数字标识
     69             continue;
     70         }
     71         /* 数字进后缀表达式结构体数组的数字 */
     72         if(flag) 
     73         {
     74             out[cnt].tag = 1;
     75             out[cnt++].u.num = sum;
     76             flag = 0;
     77             sum = 0;
     78         }                
     79         /* 读取优先级高的非数字字符(字符')'优先级0) 或者 操作符栈为空 */
     80         if(priority(str[i])>priority(top(&cstack))||isempty(&cstack))
     81         {
     82             push(&cstack, str[i]);
     83             continue;
     84         }
     85         /* 读取的字符是右括号,一次处理完括号内数字操作符包括'('*/
     86         if(str[i] == ')')
     87         {
     88             while(top(&cstack) != '(')
     89             {
     90                 out[cnt].tag = 2;
     91                 out[cnt].u.ch = top(&cstack); //操作符进后缀表达式数组的字符
     92                 cnt++;
     93                 pop(&cstack);
     94             }
     95             pop(&cstack);// '('
     96             continue;
     97         }
     98         /* 处理括号外数字及操作符*/
     99         while(!isempty(&cstack)&&top(&cstack)!='(')
    100         {
    101             out[cnt].tag = 2;
    102             out[cnt++].u.ch = top(&cstack);//操作符进后缀表达式数组的字符
    103             pop(&cstack);
    104         }
    105         /* 低级别操作符入栈 */
    106         if(str[i])
    107             push(&cstack,str[i]);
    108     }
    109     /* 打印后缀表达式 */  //100 2 3 + * 4 -   100*(2+3)-4
    110     for(i=0;i<cnt;++i)
    111     {
    112         if(out[i].tag==1)
    113             printf("%d ",out[i].u.num);
    114         else printf("%c ",out[i].u.ch);
    115     }
    116     printf("
    ");
    117 #ifdef N   
    118     /* 2.根据后缀表达式计算(用操作符栈数字栈) */     
    119     for(i=0;i<cnt;i++) 
    120     {
    121         /* 从后缀表达式结构体数组读取,是数字压数字栈,
    122         然后判断结构体数组是否读完 */
    123         if(out[i].tag == 1){
    124             push(&istack,out[i].u.num); 
    125             continue;
    126         }
    127         else if(out[i].u.ch=='+'){//数字栈顶元素加到下面元素并弹出栈顶元素
    128             istack.u.idata[istack.top-1] += top(&istack);
    129             pop(&istack);            
    130         }else if(out[i].u.ch=='-'){//同理减到下面元素并弹出栈顶元素
    131             istack.u.idata[istack.top-1] -= top(&istack);
    132             pop(&istack);
    133         }else if(out[i].u.ch=='*'){ //同理乘到下面元素并弹出栈顶元素
    134             istack.u.idata[istack.top-1] *= top(&istack);
    135             pop(&istack);
    136         }else if(out[i].u.ch=='/'){ //同理除到下面元素并弹出栈顶元素
    137             istack.u.idata[istack.top-1] /= top(&istack);
    138             pop(&istack);
    139         }else if(out[i].u.ch=='^'){//同理幂到下面元素并弹出栈顶元素
    140             istack.u.idata[istack.top-1] 
    141                 = pow(istack.u.idata[istack.top-1], top(&istack));
    142             pop(&istack);
    143         }
    144         
    145         for(j=0;j<=istack.top;++j)//一趟后剩余的数字栈遍历打印
    146             printf("%d ",istack.u.idata[j]);
    147         for(j=i+1;j<cnt;++j) //一趟后剩余的后缀表达式数字或操作符打印
    148         {
    149             if(out[j].tag==1)
    150                 printf("%d ",out[j].u.num);
    151             else printf("%c ",out[j].u.ch);
    152         }          
    153         printf("
    ");
    154     }    
    155 #endif
    156     return 0;
    157 }
    158 
    159 /* 是否栈空函数 */
    160 bool isempty(stack *s){ 
    161     return (s->top == -1);
    162 }
    163 
    164 /* 压栈函数 */
    165 void push(stack *s, int ch){
    166     if(s->tag == 0){
    167         s->u.cdata[++s->top] = (char)ch;
    168     }
    169     else{
    170         s->u.idata[++s->top] = ch;      
    171     }         
    172 }
    173 
    174 /* 弹栈函数 */
    175 int pop(stack *s){
    176     if(s->tag == 0){
    177         return s->u.cdata[s->top--];
    178     }
    179     return s->u.idata[s->top--];
    180 }
    181 
    182 /* 取栈顶元素函数 */
    183 int top(stack *s){
    184     if(s->tag == 0){
    185         return s->u.cdata[s->top];
    186     }
    187     return s->u.idata[s->top];
    188 }
    189 
    190 /* 是否数字函数 */
    191 bool isnumber(char ch){
    192     return (ch>='0'&&ch<='9');
    193 }
    194 
    195 /* 操作符优先级函数 */
    196 int priority(char ch){
    197     if(ch=='+'||ch=='-')
    198         return 1;
    199     if(ch=='*'||ch=='/')
    200         return 2;
    201     if(ch=='^')
    202         return 3;
    203     if(ch=='(')
    204         return 4;
    205     return 0;
    206 }
    栈,统一接口

      四、中缀表达式计算

      1 /* c语言的中缀表达式计算*/
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <stdbool.h>
      6 #include <math.h>
      7 #define N 256
      8 
      9 /* 栈结构体 */
     10 typedef struct{
     11     short tag; //判断类型
     12     union{         
     13         int* idata;    //整形指针    
     14         char* cdata;//字符型指针
     15     }u;     
     16     int top;
     17 }stack;
     18 
     19 /* 栈操作函数声明 */
     20 void push(stack*, int);  //压栈
     21 int pop(stack*);         //出栈
     22 int top(stack*);         //栈顶元素
     23 void calculate(stack *ist, stack *cst);//计算
     24 bool isempty(stack*);    //栈空
     25 int priority(char);      //运算符优先级
     26 bool isnumber(char);     //字符数字
     27 char* StrOperation(char* r);//字符串整理
     28 int match(char ch);      //字符匹配
     29 
     30 int main()
     31 { 
     32     stack istack, cstack;//数字栈 运算符栈
     33     
     34     istack.tag = 1;
     35     istack.u.idata = (int*)malloc(sizeof(int)*N);
     36     istack.top = -1;  //数字栈空
     37     
     38     cstack.tag = 0;  
     39     cstack.u.cdata = (char*)malloc(sizeof(char)*N);    
     40     cstack.top = -1; //运算符栈空
     41     
     42     char str[N];//中缀表达式字符串
     43     int sum = 0;//累加数字
     44     
     45     gets(str);//读取中缀表达式字符串(含空白符的字符串) 
     46     StrOperation(str); //整理字符串    
     47     printf("%s
    " ,str);
     48     
     49     int len = strlen(str);//读取的中缀表达式字符串长度
     50     int flag = 0;//是数字标识
     51         
     52     for(int i=0; i<=len ; i++) // 100*(2+3)-4   100 2 3 + * 4 -  
     53     {   //---------------------------------第一, 数字运算符进栈
     54         if(isnumber(str[i]))//累加数字   
     55         {
     56             sum = sum*10 + str[i] - '0';          
     57             flag = 1;//是数字标识
     58             continue; 
     59         }
     60         //1.数字进栈
     61         if(flag)/*为了保证最后一个数字进数字栈, 读到字符串结束标记时也要循环一次 */ 
     62         {    
     63             push(&istack, sum);//数字进栈                   
     64             flag = 0;
     65             sum = 0;
     66         }
     67         //2.运算符栈入栈(高级运算符)
     68         /* 栈空或运算符优先级比栈顶高,运算符入栈保证下面可以正常运算 */
     69         if(priority(str[i])>priority(top(&cstack))||isempty(&cstack))    
     70         {
     71             push(&cstack, str[i]);
     72             continue;
     73         } 
     74         //----------------------------------第二, 处理括号内数字运算符
     75         //3.处理括号里的操作数运算符
     76         /* 计算数字栈, 数字栈运算符栈出栈 最后'('运算符出栈*/
     77         if(str[i] == ')')
     78         {
     79             while(top(&cstack) != '(')
     80             {
     81                 calculate(&istack,&cstack);    
     82             }
     83             pop(&cstack);//'(' 出栈
     84             continue; //返回为下次运算准备数字运算符栈
     85         }
     86         //-----------------------------------第三, 处理括号外数字运算符
     87         //4.除了'('不处理, 循环处理数字栈运算符栈 
     88         while(top(&cstack)!='('&&!isempty(&cstack))
     89         {
     90             calculate(&istack,&cstack);        
     91         }
     92         //5.确保低级运算符入运算符栈
     93         if(str[i]){ //确保最后的字符串结束标记, 不被读入运算符栈
     94             push(&cstack,str[i]);
     95         }                            
     96     }
     97     printf("%d
    ",top(&istack));
     98     return 0;
     99 }
    100 
    101 /* 是否栈空函数 */
    102 bool isempty(stack *s){ 
    103     return (s->top == -1);
    104 }
    105 
    106 /* 压栈函数 */
    107 void push(stack *s, int ch){
    108     if(s->tag == 0){
    109         s->u.cdata[++s->top] = (char)ch;
    110     }
    111     else{
    112         s->u.idata[++s->top] = ch;      
    113     }         
    114 }
    115 
    116 /* 弹栈函数 */
    117 int pop(stack *s){
    118     if(s->tag == 0){
    119         return s->u.cdata[s->top--];
    120     }
    121     return s->u.idata[s->top--];
    122 }
    123 
    124 /* 取栈顶元素函数 */
    125 int top(stack *s){
    126     if(s->tag == 0){
    127         return s->u.cdata[s->top];
    128     }
    129     return s->u.idata[s->top];
    130 }
    131 
    132 /* 表达式运算 */
    133 void calculate(stack *ist, stack *cst)
    134 {
    135     switch(top(cst)){    
    136         case '+':ist->u.idata[ist->top-1] += top(ist);break;
    137         case '-':ist->u.idata[ist->top-1] -= top(ist);break;
    138         case '*':ist->u.idata[ist->top-1] *= top(ist);break;
    139         case '/':ist->u.idata[ist->top-1] /= top(ist);break;
    140         case '^':ist->u.idata[ist->top-1] 
    141             = pow(ist->u.idata[ist->top-1], top(ist));break;
    142     }         
    143     pop(ist);
    144     pop(cst);        
    145 }
    146 
    147 /* 是否数字函数 */
    148 bool isnumber(char ch){
    149     return (ch>='0'&&ch<='9');
    150 }
    151 
    152 /* 操作符优先级函数 */
    153 int priority(char ch)
    154 {    
    155     if(ch=='+'||ch=='-')
    156         return 1;
    157     if(ch=='*'||ch=='/')
    158         return 2;
    159     if(ch=='^')
    160         return 3;
    161     if(ch=='(')
    162         return 4;
    163     return 0;
    164 }
    165 
    166 /* 字符串处理函数 */
    167 char* StrOperation(char* r){
    168     if(r==NULL)
    169         return NULL;
    170     char* t = r;
    171     while(*t)
    172     {    
    173         if(match(*t)){
    174             t++;
    175             continue;        
    176         }
    177         *t = '';
    178         strcat(r,t+1);                    
    179     }
    180     return r;
    181 }
    182 
    183 /* 字符匹配函数 */
    184 int match(char ch){
    185     char key[] = "+-*/^()0123456789";
    186     for(int i=0; key[i]; ++i)
    187         if(ch == key[i]) return 1;
    188     return 0;        
    189 }
    中缀表达式计算,包括整理字符串

      五、结构体数组表示中缀表达式

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {    
        short tag;
        union {
            double num;
            char ch;
        }u;        
    }EXPRESSION;
    
    bool isnumber(char ch){
        return (ch>='0'&&ch<='9');
    }
    
    int main()
    {
        char str[] = "1.23*(15.1+33.26)";
    
        EXPRESSION e[7];
        int index = 0, flag = 1;
        
        for(int i=0; str[i]; ++i)
        {        
            if(isnumber(str[i])||str[i] == '.'){       
               if(flag){
                   e[index].u.num = atof(&str[i]);
                   e[index++].tag = 1;                
                   flag = 0;
               }
               continue;
           }
           e[index].u.ch = str[i];
           e[index++].tag = 0;
           flag = 1;
       }
       
       for(int i=0; i<index; ++i){
           if(e[i].tag) printf("%.2f", e[i].u.num);
           else printf("%c", e[i].u.ch);
       } 
       
       return 0; 
    }
    字符串转浮点+字符
  • 相关阅读:
    深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台
    Mesos源码分析
    Openvswitch原理与代码分析(8): 修改Openvswitch代码添加自定义action
    Openvswitch原理与代码分析(7): 添加一条流表flow
    Openvswitch原理与代码分析(6):用户态流表flow table的操作
    Openvswitch原理与代码分析(5): 内核中的流表flow table操作
    Openvswitch原理与代码分析(4):网络包的处理过程
    Openvswitch原理与代码分析(3): openvswitch内核模块的加载
    Openvswitch原理与代码分析(2): ovs-vswitchd的启动
    Openvswitch原理与代码分析(1):总体架构
  • 原文地址:https://www.cnblogs.com/GoldenEllipsis/p/10730274.html
Copyright © 2020-2023  润新知