栈的使用之计算表达式的值
2015-08-25 14:27
393 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/rics_dn/article/details/47976511
栈的一个重用应用时计算表达式的值,一般的处理方式是分两步:中缀表达式转后缀表达式;计算后缀表达式的值。
我们把平时所用的标准四则运算表达式,即“9+(3-1)*3+5/2”叫做中缀表达式。因为所有的运算符号都在两数字的中间,现在我们的问题就是中缀到后缀的转化。
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
6.最终将栈中的元素依次出栈,输出。
中缀表达式转后缀表达式实现:
char * infix2postfix(const char *infix, int len) { char *postfix = (char*)malloc(len+1); char *p = postfix; memset(postfix, 0, len+1); char stack[100] = {0}; int top = -1; int i; for (i = 0; i < len; ++i) { char c = infix[i]; if (-1 == top && !isNumber(c)) { stack[++top] = c; continue; } switch (c) { case '*': case '/': if (stack[top] == '+' || stack[top] == '-' || stack[top] == '(') { stack[++top] = c; }else { while(top != -1 && c != '(') { *(p++) = c; c = stack[--top]; } } break; case '+': case '-': if (stack[top] == '(') { stack[++top] = c; }else { while(top != -1 && c != '(') { c = stack[top]; *(p++) = c; top--; } stack[++top] = infix[i]; } break; case '(': stack[++top] = c; break; case ')': while(top != -1 && c != '(') { c = stack[top]; if(c != '(') *(p++) = c; top--; } break; default: *(p++) = c; } }//for (int i = 0; i < len; ++i) while(top != -1) { *(p++) = stack[top--]; } return postfix; }
以下是计算后缀表达式的值:
int calculate(const char *postfix, int len) { int stack[100] = {0}; int top = -1; int i; int value; int op1, op2; for (i = 0; i < len; ++i) { char c = postfix[i]; switch(c) { case '+': op1 = stack[top--]; op2 = stack[top--]; value = op2 + op1; stack[++top] = value; break; case '-': op1 = stack[top--]; op2 = stack[top--]; value = op2 - op1; stack[++top] = value; break; case '*': op1 = stack[top--]; op2 = stack[top--]; value = op2 * op1; stack[++top] = value; break; case '/': op1 = stack[top--]; op2 = stack[top--]; value = op2 / op1; stack[++top] = value; break; default: stack[++top] = book[c]; } } return value; }
已知的问题:
1.只支持单个字符的表达式
2.没有做充分的异常处理
以下是完整的代码:
//使用栈计算表达式的值,核心函数有两个,一个中缀表达式转后缀表达式, //一个计算后缀表达式的值 //只支持单个字符的表达式,没有做充分的异常处理 #include <stdio.h> #include <string.h> #include <stdlib.h> int book[] = { ['0'] = 0, ['1'] = 1, ['2'] = 2, ['3'] = 3, ['4'] = 4, ['5'] = 5, ['6'] = 6, ['7'] = 7, ['8'] = 8, ['9'] = 9 }; int isNumber(char c); //中缀表达式转后缀表达式 char * infix2postfix(const char *infix, int len); //计算表达式的值 int calculate(const char *postfix, int len); int main(void) { char *expr = "9+(3-1)*3+5/2"; char *postfix = infix2postfix(expr, strlen(expr)); printf("%s\n", postfix); int value = calculate(postfix, strlen(expr)); printf("%d\n", value); free(postfix); return 0; } int isNumber(char c) { if ('0'<= c && c <= '9') return 1; else return 0; } char * infix2postfix(const char *infix, int len) { char *postfix = (char*)malloc(len+1); char *p = postfix; memset(postfix, 0, len+1); char stack[100] = {0}; int top = -1; int i; for (i = 0; i < len; ++i) { char c = infix[i]; if (-1 == top && !isNumber(c)) { stack[++top] = c; continue; } switch (c) { case '*': case '/': if (stack[top] == '+' || stack[top] == '-' || stack[top] == '(') { stack[++top] = c; }else { while(top != -1 && c != '(') { *(p++) = c; c = stack[--top]; } } break; case '+': case '-': if (stack[top] == '(') { stack[++top] = c; }else { while(top != -1 && c != '(') { c = stack[top]; *(p++) = c; top--; } stack[++top] = infix[i]; } break; case '(': stack[++top] = c; break; case ')': while(top != -1 && c != '(') { c = stack[top]; if(c != '(') *(p++) = c; top--; } break; default: *(p++) = c; } }//for (int i = 0; i < len; ++i) while(top != -1) { *(p++) = stack[top--]; } return postfix; } int calculate(const char *postfix, int len) { int stack[100] = {0}; int top = -1; int i; int value; int op1, op2; for (i = 0; i < len; ++i) { char c = postfix[i]; switch(c) { case '+': op1 = stack[top--]; op2 = stack[top--]; value = op2 + op1; stack[++top] = value; break; case '-': op1 = stack[top--]; op2 = stack[top--]; value = op2 - op1; stack[++top] = value; break; case '*': op1 = stack[top--]; op2 = stack[top--]; value = op2 * op1; stack[++top] = value; break; case '/': op1 = stack[top--]; op2 = stack[top--]; value = op2 / op1; stack[++top] = value; break; default: stack[++top] = book[c]; } } return value; }
相关文章推荐
- .NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用
- 使用ExpressionBuilder 类 在分析页的过程中计算表达式
- .NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用
- java计算表达式的使用
- 使用栈的表达式计算程序_Makefile
- Justinmind使用教程(2)——计算表达式及条件使用方法
- 使用栈的表达式计算程序_main.c
- 使用正则表达式计算PDF文档的页数
- 字符串表达式计算 (使用DATATABLE)
- 使用栈的表达式计算程序_arith_expr.h__
- 使用栈计算多项表达式的简单实现--java
- 使用栈的表达式计算程序.arith_expr.c
- 使用后缀表达式计算表达式
- Java中使用Socket完成简单的远程计算(含粗糙界面和正则表达式判断数字类型)
- 使用XtraReport的CalculatedFiled(计算字段)实现RDLC报表中表达式
- .NET平台开源项目速览(8)Expression Evaluator表达式计算组件使用
- 使用堆栈结构进行字符串表达式("7*2-5*3-3+6/3")的计算
- 表达式计算(使用DataTable)
- Windows中使用 IDEA debug 调试时想动态看看表达式的计算值,类似Eclipse 中Debug时的右键Watch查看表达式值
- Justinmind使用教程(2)——计算表达式及条件用法