首页 > 编程知识 正文

java用栈实现一个复杂计算器,C语言栈的表达式求值算法

时间:2023-05-06 13:46:12 阅读:22370 作者:4101

主题:算术表达式求值题目描述:表达式计算是实现编程语言的基本问题之一,也是堆栈应用的典型例子。 设计显示用算子优先法评价算术表达式过程的程序。

基本要求:输入不包含来自终端的语法正确变量的整数表达式作为字符串。 教科书范例3.1 演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。

测试数据:

1 2 3 4

88-15

1024/48

1024/(48 )

(二十二) )六之二。

3-3-3

2*(62* ) 36 * (6) ) )

() (6)6)3)2)6) 2

算法思想首先将输入的文字分为运算数运算符两类。 hsdwx、操作数是参与运算的整数。 运算符是指加减乘除、左右括号以及“#”。 其中“#”标记输入的开始和结束,起到标记的作用。 这意味着用户输入必须以“#”结束。

为了实现上述程序功能,选择存储运算符和操作数的堆栈,分别存储在两个堆栈oprtnum中。 显示程序表达式边界的首先在oprt栈中压入一个‘#’。 从终端读取数据:

如果读到的是数字字符为了得到完整的数字,首先将这些数字字符依次存储在缓冲器(temp栈)中,根据权重将缓冲器的数字相加直到读运算符,生成完整的运算数,然后推入运算数栈,同时temp栈

如果读到的是运算符根据规则比较oprt堆栈顶部运算符与此运算符的优先级。 (

a .如果a.oprt堆栈顶部运算符高于此运算符,则表示此时可以进行计算。 将num堆栈按顺序堆栈两个要素a、b后,由b、oprt堆栈顶部运算符、a构成简单的公式,计算后将结果推入num堆栈。

如果b.oprt堆栈顶部运算符低于此运算符,请将运算符放入堆栈中,然后继续读取。

c.oprt堆栈顶部运算符的优先级与此运算符相同。 例如,如果左括号匹配,则表达式的开头“#”和结尾“#”匹配,则不堆栈此运算符,而是堆栈oprt堆栈顶部运算符。

重复上述的操作,直到oprt堆栈的开头要素为“#”或读取的字符为“#”()结束)。 num堆栈的顶级元素就是此表达式的结果。

上图是运算优先级的关系图

33558 www.Sina.com/# include stdio.h # include stdlib.h # definedefaultsize 10 # defineincreasesize 5类型化结构{ char int stacksize; //堆栈存储容量}OPRTstack; 类型结构{ double * base; 双精度*顶; int stacksize; }NUMstack; intcreatestack(oprtstack*s ) s-base=(char * ) malloc (sizeof ) char ) ) *defaultsize ); if (! s-base (返回0; s-top=s-base; s-stacksize=10; 返回1; }intpop(oprtstack*s,char *e ) if ) s-top==s-base ) return 0; s-top----; *e=*(s-top; 返回1; }intpush(oprtstack*s,char e ) if ) s-top-s-base=s-stacksize ) s-base=(char e ) realloc ) s-base,size s-base (返回0; s-top=s-base s-stacksize; s-stacksize=increasesize; }*(s-top )=e; s-top; }intisempty(oprtstack*s ) if ) s-top==s-base ) return 1; else return 0; }chargettop(oprtstack*s ) if (! isempty(s ) ) {char*temp=s-top; temp----; 返回* (temp; }else return '!' ; //这样定义的话,不能存储在堆栈中! 此数据}语音堆栈(oprtstack * s ) if (isempty ) s ) )返回; for(intI=0; is-top-s-base; I ) printf('%c ',s-g

t;base[i]);}printf(" ");}//看起来代码很多,其实下面的函数定义和上面的几乎一模一样,只是传递的参数不同而已int createStack(NUMstack*s){s->base=(double*)malloc(sizeof(double)*defaultsize);if(!s->base)return 0;s->top=s->base;s->stacksize=10;return 1;}int pop(NUMstack *s,double *e){if(s->top==s->base)return 0;s->top--;*e=*(s->top);return 1;}int push(NUMstack*s,double e){if(s->top-s->base>=s->stacksize){s->base=(double*)realloc(s->base,sizeof(double)*(s->stacksize+increasesize));if(!s->base)return 0;s->top=s->base+s->stacksize;s->stacksize+=increasesize;}*(s->top)=e;s->top++;}int isEmpty(NUMstack *s){if(s->top==s->base)return 1;else return 0;}double GetTop(NUMstack *s){if(!isEmpty(s)){double *temp=s->top;temp--;return *(temp);}else return -1;//这样定义的话,栈里面不能存储!这个数据 }void showStack(NUMstack*s){if(isEmpty(s))return ;for(int i=0;i<s->top-s->base;i++){printf("%f ",s->base[i]);}printf(" ");}int isOPRT(char c)//判断c是不是运算符 {if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='#')return 1;else return 0;}char compare(char a,char b){if(a=='+'){if(b=='*'||b=='/'||b=='(') return '<';else return '>';}else if(a=='-'){if(b=='*'||b=='/'||b=='(') return '<';else return '>';}else if(a=='*'){if(b=='(')return '<';else return '>';}else if(a=='/'){if(b=='(')return '<';else return '>';}else if(a=='('){if(b==')')return '=';else if(b=='#') return '!';else return '<';}else if(a==')'){if(b=='(')return '!';else return '>';}else if(a=='#'){if(b==')')return '!';if(b=='#')return '=';else return '<';}}double calculate(double left,double right, char operators){switch(operators){case '+':return left+right;case '-':return 1.0*left-right;case '*':return left*right;case '/':return 1.0*left/right;}}int main(){OPRTstack oprt;//运算符栈 NUMstack num;//运算数字栈 NUMstack temp;//缓冲区,用于构建完整的运算数字 int build=0;//由若干数位构成的数字 double index;//某个数位上的数字 int complex=1;//10的幂次 char operators;//基本表达式中的四则运算符 double left,right;//基本表达式中左右运算数字 createStack(&num);createStack(&oprt);createStack(&temp);printf("键入运算表达式,以#结束n"); push(&oprt,'#');char c=getchar();int error=0;//syntax error 标识符 while(c!='#'||GetTop(&oprt)!='#'){while(!isOPRT(c))//读入的是数字 {push(&temp,c-'0');c=getchar();}while(!isEmpty(&temp))//将读取到的数字字符存入缓冲区,构建完整的运算数字 {pop(&temp,&index);build+=(index*complex);complex*=10 ;}complex=1;if(build)push(&num,double(build));//将此运算数字压入栈num printf("n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);//每次压栈弹栈都需要打印信息 build=0;if(isOPRT(c))//读入的是运算符 {switch(compare(GetTop(&oprt),c)){case '<':push(&oprt,c);c=getchar();printf("n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num); break;case '=':pop(&oprt,&operators);c=getchar();printf("n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);break;case '>':pop(&oprt,&operators);pop(&num,&right);pop(&num,&left);push(&num,calculate(left,right,operators));//从num栈弹出两个运算数字,利用运算符栈顶元素进行计算 printf("n运算符栈:");showStack(&oprt);printf("运算数栈:");showStack(&num);break;case '!':printf("Syntax Error!");error=1;break;}}if(error)break;}if(!error)printf("结果为:%f",GetTop(&num));return 0;} 运行结果
测试数据8:(((6+6)*6+3)*2+6)*2#
输出:312.000000

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。