一、中缀表达式转后缀表达式并计算,后缀表达式字符串形式,数字限定小于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 }