用自定义的栈实现算术表达式求值
基本思想就是把中缀表达式通过栈转换为后缀表达式,然后利用后缀表达式求值。当然可以换成STL里的栈。但如果都用STL了还学什么数据结构嘛。看不懂留言。
#include <iostream>
#include <string>
using namespace std;
#define max 88
//luosansui's Sequential stack
//构建一个栈的数据类型
struct stack {
string* m_sq = new string[max];
int top = -1;
};
//定义操作数优先级
void priority(char singleSym, int& p) {
switch (singleSym) {
case '#':
p = -1;
break;
case '(':
p = 0;
break;
case '+':
p = 1;
break;
case '-':
p = 1;
break;
case '*':
p = 2;
break;
case '/':
p = 2;
break;
case ')':
p = 3;
break;
}
}
//判断操作数优先级,并合成一个栈
void judgePriority(stack& fig, stack& sym, char singleSym, int e, int s) {
if (e == 0) {
//压入
sym.m_sq[++sym.top] = singleSym;
}
else if (e == 3) {// 22+15*(33-27)/3
//弹出
while (sym.m_sq[sym.top][0] != '(') {
fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
}
sym.top--;
}
else if (e > s) {
//压入
sym.m_sq[++sym.top] = singleSym;
}
else if (e <= s) {
//弹出
while (e <= s) {
fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
priority(sym.m_sq[sym.top][0], s);
}
//压入
sym.m_sq[++sym.top] = singleSym;
}
}
//最后弹出所有的
void lastJudgePriority(stack& fig, stack& sym) {
while (sym.m_sq[sym.top][0] != '#') {
//弹出
fig.m_sq[++fig.top] = sym.m_sq[sym.top--];
}
}
//判断是否为操作符
bool IsSymbol(char isSym) {
switch (isSym) {
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
return true;
default:
return false;
}
}
//转换为后缀表达式
stack& conversion(string& exp, stack& sym, stack& fig) {
//分解算术表达式
for (int i = 0; i < (int)exp.length(); i++) {
//将数字压入栈
if (!IsSymbol(exp[i])) {
//将第一个数字压入fig栈
++fig.top;
fig.m_sq[fig.top] = exp[i];
//判断下一个是否为字符型数字
while (exp[i + 1] != NULL && !IsSymbol(exp[i + 1])) {
fig.m_sq[fig.top] += exp[i + 1];
i++;
}
}
else {
int a, b;
//定义&判断操作数优先级
priority(exp[i], a);
priority(sym.m_sq[sym.top][0], b);
judgePriority(fig, sym, exp[i], a, b);
}
}
lastJudgePriority(fig, sym);
delete[] sym.m_sq;
//显示后缀表达式
cout << "后缀表达式为:";
for (int i = 0; i < 20; i++)
{
cout << fig.m_sq[i] << " ";
}
cout << endl;
//返回结果
return fig;
}
//计算
double cal(string a, string b, char c) {
double x = atof(a.c_str());
double y = atof(b.c_str());
switch (c) {
case '+':
y = x + y;
break;
case '-':
y = x - y;
break;
case '*':
y = x * y;
break;
case '/':
y = x / y;
break;
}
return y;
}
//提取应运算的运算数与操作符
void calculate(stack& sta) {
string a, b;
for (int i = 0; i <= sta.top; i++) {
if (IsSymbol(sta.m_sq[i][0])) {
b = sta.m_sq[i - 1];
sta.m_sq[i - 1] = "";
for (int j = i - 2; j > -1; j--) {
if (!IsSymbol(sta.m_sq[j][0])&& sta.m_sq[j]!= "") {
a = sta.m_sq[j];
sta.m_sq[j] = "";
break;
}
}
sta.m_sq[i] = to_string(cal(a, b, sta.m_sq[i][0]));
}
}
double lss = atof(sta.m_sq[sta.top].c_str());
cout << lss << endl;
delete[] sta.m_sq;
}
//过滤用户输入的表达式中的空格
void filter(string& exp) {
int num = 0;
for (int i = 0; i < (int)exp.length() -1; i++){
for (int j = 0; j < (int)exp.length() - i - 1; j++) {
if (exp[j] == ' ') {
exp[j] = exp[j + 1];
exp[j + 1] = ' ';
}
}
}
for (int i = (int)exp.length(); i > -1; i--){
if (exp[i] == ' ') {
num++;
}
}
exp = exp.substr(0,exp.length() - num);
}
int main() {
//提示用户输入算术表达式
string expression;
cout << "请输入算术表达式" << endl;
//cin >> exp;
getline(cin, expression);
//过滤
filter(expression);
//构建两个栈,一个存放符号,一个存放数字
stack symbol, figures;
symbol.m_sq[0] = '#';
symbol.top = 0;
//计算
stack sta = conversion(expression, symbol, figures);
calculate(sta);
system("pause");
return 0;
}