没什么新意(不仅仅处理个位数算吗?)啦,就是练练手,现在写代码的能里有所下降啊。呵呵 以后每天至少写一段代码,长度>=200吧。
代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<ctype.h> 5 //文件实现四则运算,主要原理1:后缀表达式 2:栈的使用 6 //步骤1,将中缀表达式转成后缀(因为这样就可以排除括号,后缀表达不需要括号) 7 //步骤2,根据后缀表达式计算结果 8 9 //优先级分为4级,分为栈内和栈外 10 //inp: */:3 +/-:2 (:1 11 //out: (:4 */:3 +/-:2 ):0 12 13 14 //a是栈顶符号,b是扫描到的符号 15 int compare(const char a,const char b) 16 { 17 int la=0;int lb=0; 18 //注意这里的a是已经在栈内的符号,所以(的优先级就变得最低了,此外不会遇到)因为遇到)的情况都会被处理掉的 19 switch(a) 20 { 21 case '*':case '/': 22 { 23 la = 3;break; 24 } 25 case '+':case'-': 26 { 27 la = 2;break; 28 } 29 case'(': 30 { 31 la =1;break; 32 } 33 default: 34 { 35 printf("unknown symbol in the stack!n"); 36 exit(-1); 37 } 38 } 39 //b是所遇到的表达式里的符号,所以(的优先级最高,并且)的优先级最低,而且一定要处理到第一个匹配的(的位置 40 switch(b) 41 { 42 case'(': 43 { 44 lb=4;break; 45 } 46 case '*':case'/': 47 { 48 lb=3;break; 49 } 50 case'+':case'-': 51 { 52 lb=2;break; 53 } 54 case')': 55 { 56 lb=0;break; 57 } 58 default: 59 { 60 printf("unknown symbol in the expretion!n"); 61 exit(-1); 62 } 63 } 64 return (la-lb); 65 } 66 67 68 69 //将前缀表达式转换为后缀表达式 70 char* trans2back(const char* mid) 71 { 72 int len = strlen(mid); 73 char* copy_mid = (char*)malloc((len+1)*sizeof(char)); 74 char* tmp = copy_mid; 75 strcpy(tmp,mid); 76 77 char* stack = (char*)malloc(len*sizeof(char)); 78 int top = -1; 79 80 char* rt = (char*)malloc((len*2+1)*sizeof(char)); 81 char* back = rt; 82 while(*tmp!=' ') 83 { 84 switch(*tmp) 85 { 86 //遇到符号的情况下(对于‘)’ )我们要特殊处理 87 case'+':case'-':case'*':case'/':case'(': 88 { 89 *back++=' ';//this is for the token between each number 90 if(top==-1) 91 { 92 stack[++top]=*tmp; 93 } 94 else 95 { 96 while(top>=0 && compare(stack[top],*tmp)>=0) 97 { 98 *back++=stack[top]; 99 100 top--;101 }102 stack[++top]=*tmp;103 }104 break;105 }106 case ')':107 {108 while(top>=0 && stack[top]!='(')109 {110 *back++=stack[top--];111 }112 if(top<0)113 {114 printf("patten error!n");115 exit(-1);116 }117 top--;118 break;119 }120 default:121 {122 *back++=*tmp;123 break;124 }125 }//end of switch126 tmp++;127 }//end of while128 //deal with the left operator129 if(top >= 0)130 while(top>=0)131 {132 *back++=stack[top--];133 }134 *back=' ';135 free(copy_mid);136 free(stack);137 return rt;138 }139 140 int isop(char a)141 {142 if(a=='*'||a=='/'||a=='+'||a=='-')143 return 1;144 else145 return 0;146 }147 148 double op(double a,double b,char op)149 {150 switch(op)151 {152 case'+':153 {154 return a+b;155 }156 case '-':157 {158 return a-b;159 }160 case '*':161 {162 return a*b;163 }164 case '/':165 {166 return a/b;167 }168 default:169 {170 printf("error int op()n");171 exit(-1);172 }173 }174 printf("unknown op in op()n");175 exit(-1);176 177 }178 179 double caculate(const char* back)180 {181 double* stack = (double*)malloc(strlen(back)*sizeof(double));182 int top=-1;183 const char* p=back;184 const char* q=p;185 double result;186 while(*q!=' ')187 {188 if(isalnum(*q))189 {190 p=q;191 while(isalnum(*q))192 {193 q++;194 }195 stack[++top]=(double)atoi(p);196 //printf("add num %lf n",stack[top]);197 }198 else if(*q == ' ')199 q++;200 else if(isop(*q))201 {202 //printf("the op is %c and the num is %lf and %lfn",*q,stack[top],stack[top-1]);203 result = op(stack[top-1],stack[top],*q);204 stack[--top]=result;205 q++;206 }207 }208 free(stack);209 return result;210 }211 212 213 214 215 216 int main()217 {218 char expression[100];219 while(1)220 {221 fgets(expression,100,stdin);222 expression[strlen(expression)-1]=' ';223 224 char* back = trans2back(expression);225 226 printf("the back expression is %sn",back);227 228 printf("the result is %lfn",caculate(back));229 230 free(back);231 }232 return 0;233 234 }235 236 237 238 239 240
现在老忘记事先保存要free掉的指针,然后再去free移动过的指针,所以老是出现一堆core dump...杯具。
另外,c貌似写这些代码的时候很不给力啊,栈实现,字符串处理什么的没有c++来的方便快捷。
原文链接: https://www.cnblogs.com/wwillforever/archive/2010/11/08/1871865.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17100
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!