表达式求值

来源:互联网 发布:手机浏览器 域名劫持 编辑:程序博客网 时间:2024/05/16 11:12
//表达式求值基本思路://第一步:中缀表达式转后缀表达式即逆波兰表达式/*规则: 从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后        缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低        于栈顶符号(乘除优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直        到最终输出后缀表达式为止。*///第二步:进行逆波兰表达式求值/*规则:  从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符       号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。*///详解见大话数据结构#include <stdio.h>#include <ctype.h>#include <stdlib.h>#define STACK_INIT_SIZE 20#define STACKINCREMENT 10#define MAXBUFFER 30typedef double ElemType;typedef char ElemType1;char str[MAXBUFFER];char operation[MAXBUFFER];int prior[50];typedef struct  {ElemType *base;ElemType *top;int stacksize;}SqStack;typedef struct  {ElemType1 *base;ElemType1 *top;int stacksize;}SqStack1;SqStack s;SqStack1 Symble;InitStack(SqStack &S){S.base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));if (!S.base){exit(0);}S.top=S.base;S.stacksize=STACK_INIT_SIZE;}Push(SqStack &S,ElemType e){if (S.top-S.base>=S.stacksize){S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));if (!S.base){   exit(0);}S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;}int Pop(SqStack &S,ElemType &e){if (S.top==S.base){return -1;}else{e=*(--S.top);return 0;}}InitStack1(SqStack1 &S){S.base=(ElemType1 *)malloc(STACK_INIT_SIZE*sizeof(ElemType1));if (!S.base){exit(0);}S.top=S.base;S.stacksize=STACK_INIT_SIZE;}Push1(SqStack1 &S,ElemType1 e){if (S.top-S.base>=S.stacksize){S.base=(ElemType1 *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType1));if (!S.base){   exit(0);}S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;}int Pop1(SqStack1 &S,ElemType1 &e){if (S.top==S.base){return -1;}else{e=*(--S.top);return 0;}}char  GetTopElem1(SqStack1 S){if (S.top==S.base)return '\0';elsereturn *(S.top-1);}void priorarray()  //优先级数组{prior[0]=-1;  //空栈prior[40]=0;  //左括号prior[43]=1;  //加号prior[45]=1;  //减号prior[42]=2;  //乘号prior[47]=2;  //除号}int Prior(char str1,char str2) //获取优先级,{if (prior[str1]>=prior[str2]){return 1;}elsereturn 0;}void MidToBack(char* operation) //中缀表达式转后缀表达式{int i=0;char e;while(*operation!='\0'){if(isdigit(*operation)||*operation=='.')//如果是数字就输出{str[i++]=*operation;if (!isdigit(*(operation+1))&&*(operation+1)!='.'){str[i++]=' ';//数字和数字,数字和运算符之间用空格隔离,便于解析}}else //否则进行栈操作{switch(*operation){case '-':case '+':case '*':case '/':if(Prior(*operation,GetTopElem1(Symble)))//如果优先级高于栈顶元素{Push1(Symble,*operation); //则入栈}else   {while (GetTopElem1(Symble)!='('&&GetTopElem1(Symble)!=0){Pop1(Symble,e); //如果低于栈顶元素,则栈顶元素依次出栈,知道栈为空,或栈顶元素为左括号str[i++]=e;}Push1(Symble,*operation);//将本次运算符进栈}break;case '(':   //直接进栈Push1(Symble,*operation);break;case ')':  //消括号    while (GetTopElem1(Symble)!='('){Pop1(Symble,e);str[i++]=e;}Pop1(Symble,e);break;}}operation++;}while (GetTopElem1(Symble)!=0) //栈顶元素全部出栈{Pop1(Symble,e);str[i++]=e;}str[i]='\0';}int Cal(char *operation,double *final) //逆波兰表达式求值{char temp[11];int i=0;double d,e;while (*operation!='\0'){if(isdigit(*operation)||*operation=='.'){temp[i++]=*operation;if (i>=10){printf("出错:输入的单个数据过大!\n");exit(1);}}else if (*operation==' ') //字符串转浮点{temp[i]='\0';d=atof(temp);Push(s,d);i=0;}elseswitch(*operation) {case '+':Pop(s,e);Pop(s,d);Push(s,d+e);break;case '-':Pop(s,e);Pop(s,d);Push(s,d-e);break;case '*':Pop(s,e);Pop(s,d);Push(s,d*e);break;case '/':Pop(s,e);Pop(s,d);if (e!=0){Push(s,d/e);}else{printf("\n出错:除数为零!\n");return -1;}break;}operation++;}Pop(s,d);*final=d;}int main(){double final;InitStack1(Symble); //初始化运算符栈InitStack(s); //初始化数字栈printf("请输入表达式\n");scanf("%s",operation);priorarray(); //初始化优先级数组MidToBack(operation); //调用中转后Cal(str,&final);//逆波兰求值printf("\n最终的计算结果为:%f\n",final);return 0;}
<img src="http://img.blog.csdn.net/20140903112457414?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU3VuMTk5MTAxMTQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />

0 0
原创粉丝点击