栈的应用:计算字符串表达式
2017-08-29 13:42
381 查看
说明:
1. 通过栈来实现字符串公式的运算;2. 中缀转后缀:
遍历中缀表达式中的数字和符号
对于数字: 直接输出
对于符号:
->左括号: 进栈
->符号: 与栈顶符号进行优先级比较
栈顶符号的优先级低: 符号进栈
栈顶符号的优先级高: 将栈顶符号弹出并输出,之后进栈
->右括号: 将栈中的所有符号弹出并输出
3. 计算后缀的值:
遍历后缀表达式中的数字和符号
对于数字: 进栈
对于符号:
->从栈中弹出右操作数
->从栈中弹出左操作数
->根据符号进行运算
->将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果
4. 这里采用了代码复用的方法,即使用了LinkList链表和LinkStack链栈,详见《LinkList单向链表》和 《LinkStack链栈》;
代码:
main.c#include <stdio.h> #include "LinkStack.h" //输出 void output(char c) { if (c != '\0') { printf("%c", c); } } //判断是否为数字 int isNumber(char c) { return ('0' <= c) && (c <= '9'); } //判断是否为操作符 int isOperator(char c) { return (c == '+') || (c == '-') || (c == '*') || (c == '/'); } //是否为'(' int isLeft(char c) { return (c == '('); } //是否为')' int isRight(char c) { return (c == ')'); } //比较优先级 int priority(char c) { int ret = 0; if ((c == '+') || (c == '-')) { ret = 1; } if ((c == '*') || (c == '/')) { ret = 2; } return ret; } //字符转数字 int value(char c) { return (c - '0'); } //计算左右操作数的值 int express(int left, int right, char op) { int ret = 0; switch (op) { case '+': ret = left + right; break; case '-': ret = left - right; break; case '*': ret = left * right; break; case '/': ret = left / right; break; default: break; } return ret; } //中缀转后缀,返回后缀字符串,并输出 char* transform(const char* exp) { LinkStack* stack = LinkStack_Create(); char* ret = (char*)malloc(100 * sizeof(char)); memset(ret, '\0', 100 * sizeof(char)); int j = 0; int i = 0; while (exp[i] != '\0') { int i = 10 * (1 + 5) + 5; //判断是否为数字 if (isNumber(exp[i])) { output(exp[i]); ret[j++] = exp[i]; } //判断是否为操作符 else if (isOperator(exp[i])) { //遍历栈内符号,如果当前操作符的优先级小于栈顶的操作符,则弹出栈顶,并输出 while (priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack))) { output(ret[j++] = (char)(int)LinkStack_Pop(stack)); } //将当前操作符压入栈 LinkStack_Push(stack, (void*)(int)exp[i]); } //判断是否为'(' else if (isLeft(exp[i])) { LinkStack_Push(stack, (void*)(int)exp[i]); } //判断是否为')' else if (isRight(exp[i])) { char c = '\0'; //遍历栈内元素,弹出非 '(' 的元素 while (!isLeft((char)(int)LinkStack_Top(stack))) { output(ret[j++] = (char)(int)LinkStack_Pop(stack)); } //弹出'(' LinkStack_Pop(stack); } else { printf("Invalid expression!"); break; } i++; } //弹出栈内所有元素 while ((LinkStack_Size(stack) > 0) && (exp[i] == '\0')) { output(ret[j++] = (char)(int)LinkStack_Pop(stack)); } LinkStack_Destroy(stack); return ret; } //计算整个表达式的值 int compute(const char* exp) { LinkStack* stack = LinkStack_Create(); int ret = 0; int i = 0; while (exp[i] != '\0') { if (isNumber(exp[i])) { LinkStack_Push(stack, (void*)value(exp[i])); } else if (isOperator(exp[i])) { int right = (int)LinkStack_Pop(stack); int left = (int)LinkStack_Pop(stack); int result = express(left, right, exp[i]); LinkStack_Push(stack, (void*)result); } else { printf("Invalid expression!"); break; } i++; } if ((LinkStack_Size(stack) == 1) && (exp[i] == '\0')) { ret = (int)LinkStack_Pop(stack); } else { printf("Invalid expression!"); } LinkStack_Destroy(stack); return ret; } int main() { printf("8 * 2 + 1 - ( 5 - 1 ) / 2 + 2 - 1\n中缀转后缀后结果为:"); char* _strExpression = transform("8*2+1-(5-1)/2+2-1"); printf("\n"); printf("计算结果为:%d ", compute(_strExpression)); printf("\n"); system("pause"); return 0; }
函数结构分析:
1.isNumber2.isOperator
3.isLeft
4.isRight
5.priority
6.express
7.transform
8.compute
相关文章推荐
- 栈的应用--计算字符串表达式
- 输入一个字符串表达式,输出计算结果(队列、栈的应用)
- 栈的应用--计算字符串表达式
- ActionScript 3.0 学习(九) AS3 一个应用正则表达式替换字符串的例子
- 计算出用字符串表示的数学表达式的值
- .Net实现表达式计算(公式) 表达式字符串
- 字符串四则运算表达式的计算(华为机试)
- 蓝桥杯-表达式计算-栈的应用
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 字符串表达式计算C#程序设计
- C# 利用正则表达式进行忽略大小写的字符串替换的应用--自定义高亮显示
- 字符串输入计算表达式
- 正则表达式法计算字符串算术表达式2
- Java解析字符串表达式--逆波兰表达式的计算
- 取得一个字符串表达式的计算结果(实现方法二)
- 字符串四则运算表达式的计算(华为机试)
- Java中计算字符串表达式的好办法
- 栈的应用---用栈计算逆波兰表达式
- 利用API 实现字符串表达式的计算
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java) (转载)