BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / soft-design / #21608同步于 2007/10/8
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖

贴个表达式计算的程序,应该大家都做过吧

Rukawa
2007/10/8镜像同步11 回复
/*为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= **************表达式计算器************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <malloc.h> #define STACK_SIZE 100 #define APPEND_SIZE 10 struct SNode{ float data; /*存放操作数或者计算结果*/ char ch; /*存放运算符*/ }; struct Stack{ SNode *top; SNode *base; int size; }; /*栈操作函数*/ int InitStack(Stack &S); /*创建栈*/ int DestroyStack(Stack &S); /*销毁栈*/ int ClearStack(Stack &S); /*清空栈*/ int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/ int Push(Stack &S,SNode e); /*将结点e压入栈*/ int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/ /*表达式计算器相关函数*/ char get_precede(char s,char c); /*判断运算符s和c的优先级*/ int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/ float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/ float compute(); /*表达式结算器主函数*/ char *killzero(float result); /*去掉结果后面的0*/ int InitStack(Stack &S) { S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode)); if(S.base==NULL) { printf("动态分配内存失败!"); return -1; } S.top=S.base; S.size=STACK_SIZE; return 0; } int DestroyStack(Stack &S) { free(S.base); return 0; } int ClearStack(Stack &S) { S.top=S.base; return 0; } int GetTop(Stack S,SNode &e) { if(S.top==S.base) { printf("栈以为空!"); return -1; } e=*(S.top-1); return 0; } int Push(Stack &S,SNode e) { if(S.top-S.base>=S.size) { S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode)); if(S.base==NULL) { printf("动态分配内存失败!"); return -1; } S.top=S.base+S.size; S.size+=APPEND_SIZE; } *S.top=e; S.top++; return 0; } int Pop(Stack &S,SNode &e) { if(S.top==S.base) { printf("栈为空!"); return -1; } e=*(S.top-1); S.top--; return 0; } char get_precede(char s,char c) { switch(s) { case '+': case '-': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return '>'; else return '>'; case '*': case '/': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '>'; else if(c=='(') return '<'; else if(c==')') return '>'; else return '>'; case '(': if(c=='+'||c=='-') return '<'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return '='; else return 'E'; case ')': if(c=='+'||c=='-') return '>'; else if(c=='*'||c=='/') return '>'; else if(c=='(') return 'E'; else if(c==')') return '>'; else return '>'; case '#': if(c=='+'||c=='-') return '<'; else if(c=='*'||c=='/') return '<'; else if(c=='(') return '<'; else if(c==')') return 'E'; else return '='; default: break; } return 0; } int isOpr(char c) { if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=') return 0; else return 1; } float operate(float x, char opr, float y) { float result; switch (opr) { case '+': result = x + y; break; case '-': result = x - y; break; case '*': result = x * y; break; case '/': if (y == 0) { printf("Divided by zero!\n"); return 0; } else { result = x / y; break; } default: printf("Bad Input.\n"); return 0; } return result; } float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/ { Stack optr,opnd; struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t; char c; char buf[16]; int i=0; InitStack(optr); /*用于寄存运算符*/ InitStack(opnd); /*用于寄存操作数和计算结果*/ memset(buf,0,sizeof(buf)); printf("Enter your expression:"); opr_in.ch='#'; Push(optr,opr_in); /*'#'入栈*/ GetTop(optr,opr_top); c=getchar(); while(c!='='||opr_top.ch!='#') { if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/ { buf[i]=c; i++; c=getchar(); } else /*是运算符*/ { buf[i]='\0'; if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/ { opn_in.data=(float)atof(buf); Push(opnd,opn_in); printf("opnd入栈:[%f]\n",opn_in.data); i=0; memset(buf,0,sizeof(buf)); } opr_in.ch=c; switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/ { case '<': /*优先级小于栈顶结点,则运算符入栈*/ Push(optr,opr_in); printf("optr入栈:[%c]\n",opr_in.ch); c=getchar(); break; case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/ Pop(optr,e); printf("optr出栈:去掉括号\n"); c=getchar(); break; case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/ Pop(optr,opr_t); printf("optr出栈:[%c]\n",opr_t.ch); if(Pop(opnd,b)<0) { printf("Bad Input!\n"); fflush(stdin); return -1; } printf("opnd出栈:[%f]\n",b.data); if(Pop(opnd,a)<0) { printf("Bad Input!\n"); fflush(stdin); return -1; } printf("opnd出栈:[%f]\n",a.data); opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/ Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/ printf("结果入栈:[%f]\n",opn_tmp.data); break; } } GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/ } GetTop(opnd,opn_tmp); DestroyStack(optr); DestroyStack(opnd); return opn_tmp.data; } char *killzero(char *res,float result) { int i; sprintf(res,"%f",result); i=(int)strlen(res)-1; while(i&&res[i]=='0') { res[i]='\0'; i--; } if(res[i]=='.') res[i]='\0'; return res; } int main() { char ch; char res[64]; float result; while(1) { result=compute(); printf("\nThe result is:%s\n",killzero(res,result)); printf("Do you want to continue(y/n)?:") ; ch=getch(); putchar(ch); if(ch=='n'||ch=='N') break; else system("cls"); } return 0; }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
yywbupt机器人#1 · 2007/10/8
Handcraft。。。狂赞 以前学数据结构做过这个例子,没详细看你的代码,但好象就是第一次压栈由中缀表达式转成后缀表达式,第二次压栈计算它的值 后来用编译原理的词法分析和语法分析生成抽象语法,恶心死了,至今不会用lex和yacc。。。
mayao11机器人#2 · 2007/10/8
前段时间听说了 Antlr这个东西,被它的例子吸引了。编写一个类似计算器的程序非常容易,语法处理非常nb 不知各位大哥有何看法。 【 在 yywbupt (Fighting dreamers) 的大作中提到: 】 : Handcraft。。。狂赞 : 以前学数据结构做过这个例子,没详细看你的代码,但好象就是第一次压栈由中缀表达式转成后缀表达式,第二次压栈计算它的值 : 后来用编译原理的词法分析和语法分析生成抽象语法,恶心死了,至今不会用lex和yacc。。。 : ...................
Quake机器人#3 · 2007/10/8
大二的试验啊 当时我用C++写了一个,也是按照要求用栈来实现的,不过是直接使用STL的stack就是了 XDD 当时的精力主要是在表达式解析上,多做了些东西 支持+-两个一目运算符,二目运算符+-*/^,括号(),常数pi,常用函数sin, cos, sqrt等,能识别错误输入
Rukawa机器人#4 · 2007/10/9
我当时做的一个WAV播放器更搞笑 直接用MFC画了个界面,然后播放的按纽下面调用播放WAV的类,就搞定了 现在想想,太搞了,一点技术含量都没
heartremain机器人#5 · 2007/10/14
赞开源
wp机器人#6 · 2007/10/14
这个表达式处理的做法很经典阿,呵呵 用java做类似的东西,试试javacc吧,极其好用
flyingmiao机器人#7 · 2007/10/14
数据结构重新,呵,似乎当年的第一个作业,哈,相当经典。
WangZhaogang机器人#8 · 2007/10/14
【 在 Rukawa 的大作中提到: 】 : /*为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的. : 程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)= : **************表达式计算器************/ : ................... HEHE现在代码能力已经无比强了啊~
ilovekitchen机器人#9 · 2007/10/16
难道是技术帖? 竟然开始转型了...