进入主题前先废话一段,不想看直接跳到第二段吧!两年前我哥给我买了本《算法》(第四版),一直没有看,最近捡起来看看。需要吐槽的是这本《算法》是基于JAVA语言来的,而我又只会C++,纠结了半天还是不打算再学JAVA了,本来C++就不咋地。将就着看吧,正好把JAVA实现算法变成C++实现算法,能更深刻地理解这些算法了。本博客使用C++语言中双栈结构实现算术表达式求值,本人水平有限其中大量情况都没考虑(如开根号,中括号,负数等),只考虑了左右括号、加减乘除这几种情况,实现了算术表达式(1 + ( (2 + 3) * (4 * 5) ) )计算。
E.W.Dijkstra在20世纪60年代发明了一个非常简单的算法实现初级算术运算操作。该方法需要运用两个栈(操作数栈和运算符栈),方法规则如下:
1、将操作数压入操作数栈;
2、将运算符压入运算符栈;
3、忽略左括号;
4、在遇到右括号时,弹出一个运算发,弹出所需数量的操作数,并将运算符和操作数的运算结果压入操作数栈。
实现代码:
#include <iostream>
#include <stack>
#include <string>
//双栈实现算术表达式求值
int main()
{
using namespace std;
stack<char> oper; // 运算符栈
stack<double> number; // 操作数栈
string mathExpression;
getline(cin,mathExpression); //输入算术表达式
int size = mathExpression.size();
double result = 0.f;
for (int i = 0; i < size; i++)
{
char ch = mathExpression.at(i);
if (ch >= '0' && ch <= '9') //判断是否为操作数
{
double tem = atoi(&ch);
number.push(int(tem));
}
else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') //判断是否为运算符,这里只定义了加减乘除
{
oper.push(ch);
}
else if (ch == ')') //判断是否为右括号,进行计算
{
double first = number.top(); //获取第一个操作符
number.pop();
double second = number.top(); //获取第二个操作符
number.pop();
char op = oper.top(); //获取运算符
oper.pop();
//进行计算
if (op == '+')
{
result = first + second;
}
else if (op == '-')
{
result = first - second;
}
else if (op == '*')
{
result = first * second;
}
else if (op == '/')
{
result = first / second;
}
else
{
cout << "undefined operator...." << endl;
}
//将运算结果压入操作数栈
number.push(result);
}
else if (ch == '(' || ch == ' ') //忽略左括号和空格
{
}
else //未定义字符
{
cout << "undefined char..." << endl;
}
}
cout << "The result of the operation is " << result << endl;
return 0;
}
结果展示: