注:学习自《数据结构》李春葆,图自PPT
一丶算术表达式有三种类型
- 中缀表达式 1 + 2 * 3:运算符位于操作数中间
中缀表达式的运算规则:“先乘除,后加减,从左到右计算,先括号内,后括号外”
因此,中缀表达式不仅要依赖运算符优先级,而且还要处理括号
- 后缀表达式 1 2 3 * +:运算符在操作数的后面
- 已考虑了运算符的优先级
- 没有括号
- 只有操作数和运算符,而且越放在前面的运算符来越优先执行
- 前缀表达式 + 1 * 2 3:运算符位于操作数前面
我们平常使用的是中缀表达式,但后缀表达式非常好,运算的优先已经好了,所以我们用后缀表达式计算
二丶求中缀表达式
- 将中缀算术表达式转换成后缀表达式
- 对该后缀表达式求值
① 将中缀算术表达式转换成后缀表达式
算法描述
② 对该后缀表达式求值
算法描述
三丶LeetCode 有道题目
基本计算器,可以练练手
我的代码像上面写的,但是考虑了±x/(),速度和内存都用得比较多,是否可以将求解简单表达式的两个阶段合并起来?其实题目只要求了±(),精简化LeetCode上面说了好多
#include <iostream>
#include <stack>
const int MAX_SIZE = 1000000;
using namespace std;
class Solution {
public:
//exp => postexp
void trans(const char* exp, char* postexp)
{
stack<char> optr;
char e;
int i = 0;
while (*exp != '\0')
{
switch (*exp)
{
case ' ':exp++; break;
case '(':
optr.push('(');
exp++;
break;
case ')':
//出栈到此前第一个')'
e = optr.top();
optr.pop();
while (e != '(')
{
postexp[i++] = e;
e = optr.top();
optr.pop();
}
exp++;
break;
case '*':
case '/':
while (!optr.empty())
{
e = optr.top();
if (e == '*' || e == '/')
{
postexp[i++] = e;
optr.pop();
}
else
break;
}
optr.push(*exp);
exp++;
break;
case '+':
case '-':
while (!optr.empty())
{
e = optr.top();
if (e != '(')
{
postexp[i++] = e;
optr.pop();
}
else
break;
}
optr.push(*exp);
exp++;
break;
default:
while (*exp >= '0' && *exp <= '9')
{
postexp[i++] = *exp;
exp++;
}
postexp[i++] = '#';
break;
}
}
//此时exp扫描完毕,全部出栈并写入
while (!optr.empty()) {
e = optr.top();
optr.pop();
postexp[i++] = e;
}
postexp[i] = '\0';
}
double compValue(char* postexp)
{
double a, b, c, d;
stack<double> data;
while (*postexp != '\0')
{
/* code */
switch (*postexp)
{
case '+':
a = data.top(); data.pop();
b = data.top(); data.pop();
c = b + a;
data.push(c);
break;
case '-':
a = data.top(); data.pop();
b = data.top(); data.pop();
c = b - a;
data.push(c);
break;
case '*':
a = data.top(); data.pop();
b = data.top(); data.pop();
c = b * a;
data.push(c);
break;
case '/':
a = data.top(); data.pop();
b = data.top(); data.pop();
if (a != 0) {
c = b / a;
data.push(c);
break;
}
else
{
cout << "0错误";
exit(0);
}
break;
default:
d = 0;
while (*postexp >= '0' && *postexp <= '9')
{
d = 10 * d + *postexp - '0';
postexp++;
}
data.push(d);
break;
}
postexp++;
}
return data.top();
}
int calculate(string s) {
char postexp[MAX_SIZE];
const char* exp = s.data();
trans(exp, postexp);
cout << postexp<<endl;
return compValue(postexp);
}
};