中缀表达式转化为后缀表达式、后缀表达式求解(栈)
来源:互联网 发布:网络布线施工室分 编辑:程序博客网 时间:2024/06/05 14:27
计算器我们都实现了很多了,但是,我们写的计算器都是求解两个操作数的,并不能求解一个表达式,如今栈已经学完了,那么我们可不可以使用栈来实现表达式的求解呢?
我们数学上求解一个表达式是如何进行的,有括号的先求括号内部的,之后先算乘除,再算加减。现在如果来实现一个这样可以求解表达式的计算器,怎样进行呢?
首先是将中缀表达式转化为后缀表达式,具体的规则如下:
1、遇到操作数,直接输出;
2、栈为空时,遇到运算符,入栈;
3、遇到左括号,将其入栈;
4、遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;
5、遇到其他运算符’+”-”*”/’时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;
6、最终将栈中的元素依次出栈,输出。
之后就是后缀表达式的求解了,大致是这样的:
扫描后缀表达式, 如果是数字,则让其进栈; 若为操作符,则从栈中取出两个操作数,先取出的作为右操作数,后取出的作为左操作数,然后进行该操作符的运算,并使其结果入栈。 重复上述过程,直至表达式扫描完成。 最终栈中只留一个元素,就是表达式结果。
下面是具体的实现代码:
#include<iostream>using namespace std;#include<assert.h>#include<stack>//获取操作符的优先级int GetPriority(char ch, int flag)//flag为1时表示栈内优先级 flag为0表示栈外优先级{ if (ch == '+' || ch == '-') { if (flag) { return 3; } else { return 2; } } else if (ch == '*' || ch == '/' || ch == '%') { if (flag) { return 5; } else { return 4; } } else if (ch == '(') { if (flag) { return 1; } else { return 6; } } else if (ch == ')') { if (flag) { return 6; } else { return 1; } }}//中缀表达式转化后缀表达式void InfixToPostfix(char *dest, char*src){ assert(dest); assert(src); stack<char> s;//保存操作符,使其按照优先级从大到小输出 char* _cur = src;//用一个指针指向中缀表达式 char* _temp = dest;//用指针指向存储后缀表达式的空间 while (*_cur != '\0') { if (*_cur >= '0' && *_cur <= '9')//如果是数字字符,那么保存 { *_temp++ = *_cur; _cur++; continue; } //如果是操作符,那么分情况讨论 else if (*_cur == '+' ||* _cur == '-' || *_cur == '*' || *_cur == '/' || *_cur == '%' || *_cur == '(' || *_cur == ')') { if (s.empty())// { s.push(*_cur); _cur++; } else { if (*_cur == ')') { while (s.top() != '(') { *_temp++ = s.top(); s.pop(); } s.pop();//删除栈顶的‘(’ *_cur++; } //如果当前操作符的优先级大于栈顶元素的优先级,将当前操作符入栈 if (GetPriority(*_cur, 0) > GetPriority(s.top(), 1)) { s.push(*_cur); _cur++; } else { while (!s.empty() && GetPriority(*_cur, 0) < GetPriority(s.top(), 1)) { *_temp++ = s.top(); s.pop(); } s.push(*_cur); _cur++; } } } else//跳过空格 { *_temp++ = *_cur++; } } //将栈内剩余元素放入表达式 while (!s.empty()) { *_temp++ = s.top(); s.pop(); }}//后缀表达式求值(计算器)int Calculate(char *_postfix,char*_infix){ InfixToPostfix(_postfix, _infix); stack<int> s;//注意前后两个栈的使用用途不同,实例化也不同 char*_cur = _postfix; int temp = 0;//保存数字字符转化后的数字 int res = 0;//保存运算结果 while (*_cur != '\0') { if (*_cur >= '0'&&*_cur <= '9') { res = 0; while (!isspace(*_cur) && *_cur >= '0'&&*_cur <= '9') { temp = *_cur - '0';//将数字字符转化为数字 res = res * 10 + temp;// 例如:12 _cur++; } s.push(res); } else if (*_cur == '+' || *_cur == '-' || *_cur == '*' || *_cur == '/' || *_cur == '%') { int right = s.top();//先取出来的是右操作数 s.pop(); int left = s.top(); s.pop(); switch (*_cur) { case '+': s.push(left + right); break; case '-': s.push(left - right); break; case '*': s.push(left * right); break; case '/': if (right) { s.push(left / right); break; } case '%': s.push(left % right); break; } _cur++; } else//跳过空格 { _cur++; } } if (!s.empty()) { res = s.top(); s.pop(); return res; }}void FunTest(){ char* _infix = "12 * (3 + 4) - 6 + 8 / 2 "; char _postfix[20] = {}; int result = Calculate(_postfix, _infix); cout <<result << endl;}int main(){ FunTest(); return 0;}
0 0
- 中缀表达式转化为后缀表达式、后缀表达式求解(栈)
- 中缀转化为后缀表达式
- 中缀表达式转化为后缀表达式(栈的应用)
- 把中缀表达式转化为后缀表达式
- 用栈将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 中缀表达式转化为后缀表达式
- 中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 将中缀表达式转化为后缀表达式
- 中缀表达式转化为后缀表达式
- 中缀表达式转化为后缀表达式
- linux下安装mysql
- 8421码
- ZeroC Ice IceGrid Node和IceGrid
- node项目在服务器的部署
- webSocket与html区别,以及服务端与客户端消息通讯利用webSocket
- 中缀表达式转化为后缀表达式、后缀表达式求解(栈)
- bootstrap
- Android SDK no swt-pi-gtk-3550 or swt-pi-gtk in swt.library.path, java.library.path or the jar解决
- html和js实现模态框
- windows c++使用hiredis异步操作
- java 监听端口并时刻接收端口收到的信息(简单)
- python redis
- 停止线程
- 【学习笔记】查询性能优化:重构查询方式