关于表达式计算的问题
来源:互联网 发布:酷士多网络云手机 编辑:程序博客网 时间:2024/05/01 21:54
当我们需要计算一个带+ - * / ( ) 的四则运算的时候,我们需要遵循 口诀:先*/后+-乘方最优先 要是有括号就先算括号里面的
计算表达式的方法一(只展示这一过程中的中缀表达式的处理过程)
主要依据的数据结构是栈,需要两个栈,一个用于存储运算分量(operand),另一个用于存储运算符(operators)。
算法的核心思想是:从左向右读取表达式
1.读入当前的字符ch是数字,就压入运算分栈,
2.如果读入的当前字符ch是’(‘,就直接压入运算符栈
3.如果读入的当前字符ch是’+’, ‘-‘, ‘*’, ‘/’, ‘^’进行如下操作
1)将ch与运算符栈栈顶元素进行比较
2)如果ch优先级高,则把ch压入运算符栈,然后再读取字符ch从1.开始从头执行
3)如果ch优先级<=栈顶运算符优先级,则进行”栈顶运算操作”(将运算分量连续弹栈两次,运算符弹栈依次,然后将运算结果存回运算分量栈),然后返回1)执行后续算法
4.如果读入的ch==’)’,则反复执行”栈顶运算操作”,直到遇到的栈顶·元素是’(‘直接弹栈,然后读取字符并且返回1.开始执行,知道表达式计算完毕为止
最核心的思想是,对运算符栈的处理,当运算符栈为空,或当前运算符为’(‘,或者当前运算符的优先级>栈顶运算符的时候直接进行压栈,当前运算符的优先级<=栈顶运算符的时候,弹栈执行相应的运算
#include <stdio.h>#include <string.h>#define N 100char operators[N];char operand[N];int operators_top=0,operand_top=0;void push_operators(const char& op) //用数组模拟堆栈{ operators[++operators_top]=op;}char pop_operators(){ return operators[operators_top--]; //operators_top--;}char top_operators(){ return operators[operators_top];}bool empty_operators(){ if(operators_top==0) return true; else return false;}void push_operand(const char& op){ operand[operand_top++]=op;}bool isOperator(const char& ch){ switch(ch) { case '+': case '-': case '*': case '/': case '^': case '(': case ')': return true; } return false;}int priority(const char& ch){ switch(ch) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; } return 0;}void postfix(char* infix){ //char ch; for(unsigned int i=0;i<strlen(infix);i++) { if(isOperator(infix[i])) { if( infix[i]==')' ) { while((top_operators())!='(') { push_operand( pop_operators() ); } pop_operators(); } else if( empty_operators() || priority(infix[i]) > priority(top_operators()) || infix[i]=='(' ) push_operators(infix[i]); else if(priority(infix[i]) <= priority(top_operators())) { push_operand(pop_operators()); while (!empty_operators()) { if (priority(infix[i]) <= priority(top_operators())) { push_operand(pop_operators()); } else break; } push_operators(infix[i]); } } else { push_operand(infix[i]); } } while (!empty_operators()) { push_operand(pop_operators()); }}int main(){ memset(operand,0,sizeof(operand)); memset(operators,0,sizeof(operators)); char a[N]="2+3*(3-(5+3-5*4*4+0)/4)"; postfix(&a[0]); for(int i=0;i<operand_top;i++) printf("%c",operand[i]); return 0;}
计算表达式值的方法2
主要的理论依据是编译原理里面关于四则运算的递归下降的分析方法,要先写出表达式的bnf范式,然后再利用递归下降的分析方法分析bnf范式,利用递归下降的分析方法的时候必须确保消除bnf范式里的左递归
将消除左递归之后的,可以直接将bnf范式利用递归下降的方法写成代码
利用上述思想直接翻译成代码如下:
#include <stdio.h>#include <stdlib.h>enum {Num};int token;int token_val;char *src = NULL;void next() { while (*src == ' ' || *src == '\t') { src ++; } token = *src++; if (token >= '0' && token <= '9' ) { token_val = token - '0'; token = Num; while (*src >= '0' && *src <= '9') { token_val = token_val*10 + *src - '0'; src ++; } return; }}void match(int tk){ next();}int expr();int factor(){ double value = 0; if(token=='(') { match('('); value = expr(); match(')'); }else{ value = token_val; match(Num); } return value;}int term_tail(int lvalue){ if(token=='*'){ match('*'); int value = lvalue * factor(); return term_tail(value); }else if(token=='/'){ match('/'); int value = lvalue / factor(); return term_tail(value); }else{ return lvalue; }}int term(){ int value = factor(); return term_tail(value);}int expr_tail(int lvalue){ if(token=='+'){ match('+'); int value = lvalue + term(); return expr_tail(value); }else if(token=='-'){ match('-'); int value = lvalue - term(); return expr_tail(value); }else{ return lvalue; }}int expr(){ int value = term(); return expr_tail(value);}int main(){ src="2+3*(3-(5+3-5*4*4)/4)"; next(); printf("%d",expr()); return 0;}
- 关于表达式计算的问题
- 表达式计算的问题
- 关于用堆栈实现中后缀表达式计算的问题
- 续前篇-关于逆波兰表达式的计算
- 关于日期计算的问题
- 关于日期计算的问题
- 关于js计算的问题
- 关于精度计算的问题
- 关于正则表达式的问题
- 逆波兰表达式的计算问题
- 关于圆的计算 圆柱的 球的 计算问题
- 关于后缀表达式的计算与中缀表达式转化为后缀表达式
- 关于 贝叶斯 计算公式的一个问题
- 求助:关于计算列的问题!!!
- 关于BigDecimal 的不精确计算问题
- 关于级联信道的信道容量计算问题
- 【关于SimpleDateFormat 的星期计算问题】
- 关于计算解码速度的问题
- c++作业-3
- Horner规则求解多项式的值
- 四大组件之Service 前台服务
- QML的Label实现Tooltip提示效果
- 为什么一个java源文件中只能有一个public类?
- 关于表达式计算的问题
- Spark 中 map 与 flatMap 的区别
- 学习css3到底要学些什么
- Android 自定义RecyclerView布局(一)
- [Usaco2008 Oct]灌水(MST)
- BZOJ1009: [HNOI2008]GT考试
- 重命名 sql server 安装服务器
- LeetCode 21. Merge Two Sorted Lists
- iOS 动画Animation-4-3: CALayer子类:CAShapeLayer