用栈实现加减乘除
括号判断我已经完成了
// 作者QQ:1711285081 //最新修改时间:2013.6.5 22.21 // 版本:v0.2(第13次修改) // 编译器:VS2012 x64(cl biaodashi.c) GCC 4.7.2 x86(gcc biaodashi.c -o biaodashi) // 运行环境:windows server 2012 intel x86_64 // 试运行输出: // lwb603569640@windows_server_2012 /g/projects // $ biaodashi // 输入1继续计算,否则退出!1 // 输入表达式:11/11+12*13-7+8/(1+1+1-1)/8 // 中序表达式:11/11+12*13-7+8/(1+1+1-1)/8 // 后序表达式:11,11/12,13*+7-8,1,1+1+1-/8/+ // 后序表达式求值:150.500000 // 输入1继续计算,否则退出! #include <stdio.h> #include <stdlib.h> #include <string.h> int PRI(char op) //设定算符的优先级 { switch (op) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } char *toPosfix(char *infix) // 求后序表达式 { int length=strlen(infix); char *stack,*buf,*p,flag; char op; int i,top=0; if(!(stack=(char *)malloc(sizeof(char)*length))) //作为栈内存空间 { printf("内存分配失败!\n"); exit(0); } if(!(buf=(char *)malloc(sizeof(char)*length*2))) //保存后序表达式字符串 { printf("内存分配失败!\n"); exit(0); } p=buf; for(i=0;i<length;i++) { op=infix[i]; //获取表达式中一个字符 switch(op) //根据字符进行入栈操作 { case '(': //为左括号 if(top<length) //若栈未满 { top++; //修改栈顶指针 stack[top]=op; //保存运算符到栈 } flag=0; break; case '+': case '-': case '*': case '/': while(PRI(stack[top])>=PRI(op)) //判断栈顶运算符与当前运算符的级别 { *p++=stack[top]; //将栈中的运算符保存到字符串 top--; //修改栈顶指针 flag=0; } if(top<length) //栈未满 { top++; //修改栈顶指针 stack[top]=op; //保存运算符到栈 if(flag==1) *p++=','; //添加一个逗号分隔数字 flag=0; } break; case ')': //右括号 while(stack[top]!= '(') //在栈中一直找到左括号 { *p++=stack[top]; //将栈顶的运算符保存到字符串 top--; //修改栈顶指针 } flag=0; top--; //再将修改栈顶指针,将左括号出栈 break; default: //其他字符(数字、字母等非运算符) *p++=op; flag=1; break; } } while (top>0) //若栈不为空 { *p++=stack[top]; //将栈中的运算符出栈 top--; //修改栈顶指针 } free(stack);//释放栈占用的内存 *p='\0'; return (buf); //返回字符串 } double calc(double d1, char op, double d2) //计算函数 { switch (op) //根据运算符进行操作 { case '+': return d1 + d2; case '-': return d1 - d2; case '*': return d1 * d2; case '/': return d1 / d2; } return 0; } double eval(char *postfix) //计算表达式的值 { double *stack,num,k=1.0; //k为系数 int i,length,top=0,dec=0,flag;//dec为0表示整数,为1表示小数,flag=1表示有数据需入栈 char token; length=strlen(postfix); if(!(stack=(double *)malloc(sizeof(double)*length))) { printf("内存分配失败!\n"); exit(0); } num=0; for(i=0;i<length;i++) { token=postfix[i]; //取出一个字符 switch(token) { case '+': //若是运算符 case '-': case '*': case '/': if(top<length && flag==1) //若栈未满 { top++; //修改栈顶指针 stack[top]=(double)num; //将数字保存到栈中 num=0; } stack[top-1]=calc(stack[top-1], token, stack[top]);//取出栈栈前两个元素进行运算,结果保存到栈中 top--; //修改栈顶指针 dec=0;//先设为整数 flag=0;//下一步操作不将数入栈 break; default: //不为运算符 if(token==',') //若为逗号 { if(top<length) //若栈未满 { top++; //修改栈顶指针 stack[top]=(double)num; //将数字保存到栈中 num=0; dec=0; break; } } else if(token=='.') { k=1.0; dec=1; break; } if(dec==1) //小数部分 { k=k*0.1; num=num+(token-'0')*k; } else { num=num*10+token-'0'; } flag=1;//有数需要入库 break; } } return stack[top]; //返回栈顶的结果 } int main() { char infix[80]; while(1){ printf("输入1继续计算,否则退出!"); if(getchar()=='1'){ getchar(); printf("输入表达式:"); gets(infix); printf("中序表达式:%s\n\n", infix); printf("后序表达式:%s\n\n", toPosfix(infix)); printf("后序表达式求值:%lf\n\n",eval(toPosfix(infix))); }else{ exit(0); } } getch(); return 0; }