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

三世轮回 提交于 2020-05-09 10:47:06

  一、中缀表达式转后缀表达式并计算,后缀表达式字符串形式,数字限定小于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]='\0';    
100     /* 打印后缀表达式 */     //1 2 3 + * 4 -
101     for(i=0;i<cnt;++i)
102         printf("%c ",out[i]); 
103     printf("\n");
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("\n");
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("\n");
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("\n");
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("\n");
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("\n");
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\n" ,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\n",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 = '\0';
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 }
中缀表达式计算,包括整理字符串

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

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 typedef struct {    
 5     short tag;
 6     union {
 7         double num;
 8         char ch;
 9     }u;        
10 }EXPRESSION;
11 
12 bool isnumber(char ch){
13     return (ch>='0'&&ch<='9');
14 }
15 
16 int main()
17 {
18     char str[] = "1.23*(15.1+33.26)";
19 
20     EXPRESSION e[7];
21     int index = 0, flag = 1;
22     
23     for(int i=0; str[i]; ++i)
24     {        
25         if(isnumber(str[i])||str[i] == '.'){            
26             if(flag){
27                 e[index].u.num = atof(&str[i]);
28                 e[index++].tag = 1;                
29                 flag = 0;
30             }
31             continue;
32         }
33         e[index].u.ch = str[i];
34         e[index++].tag = 0;
35         flag = 1;
36     }
37     
38     for(int i=0; i<index; ++i){
39         if(e[i].tag) printf("%.2f", e[i].u.num);
40         else printf("%c", e[i].u.ch);
41     } 
42     
43     return 0; 
44 }
字符串转浮点+字符

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!