【发布时间】:2019-03-27 15:56:16
【问题描述】:
我正在尝试编写一个计算简单数学表达式的函数(只有四个操作)。我使用堆栈和向量来做到这一点。但是堆栈操作的行为并不像我预期的那样。我找不到原因。我愿意接受不同的解决方案。
函数应该接受这样的字符串:
“5 * 44 + 3 / 2 * 4 - 12”
并将结果作为双精度返回。
#include <iostream>
#include <vector>
#include <stack>
#include <string>
#include <cstdlib>
using namespace std;
vector<string> split(const std::string& str, char delim = ' ')
{
vector<string> elements;
stringstream ss(str);
string token;
while (getline(ss, token, delim)) {
elements.push_back(token);
}
return elements;
}
double evaluate(string operation)
{
vector<string> values = split(operation, ' ');
stack<string> result_stack;
double result = 0;
for(unsigned int i = 0; i < values.size(); i++){
if(values[i] == "*"){
double mini_result = stod(result_stack.top()) * stod(values[i+1]);
result_stack.pop();
i++;
result_stack.push(to_string(mini_result));
}
else if(values[i] == "/"){
double mini_result = stod(result_stack.top()) / stod(values[i+1]);
result_stack.pop();
i++;
result_stack.push(to_string(mini_result));
}
else{
result_stack.push(values[i]);
}
}
for(unsigned int i = 0; i<result_stack.size(); i++){
if(result_stack.top() == "-"){
result_stack.pop();
result = stod(result_stack.top()) - result;
result_stack.pop();
}
else if(result_stack.top() == "+"){
result_stack.pop();
result += stod(result_stack.top());
result_stack.pop();
}
else{
result += stod(result_stack.top());
result_stack.pop();
}
}
return result;
}
int main()
{
cout<<evaluate("5 * 44 + 3 / 2 * 4 - 12");
}
在第二个 for 循环之前,result_stack 中的值应该是这个例子的这个样子。 “12 | - | 6 | + | 220”。并且返回值应该是214。
但在第二个 for 循环之前,堆栈仅包含“12 | - | 6”值。 “+”和“220”值不存在。发生了一些我没想到的额外爆裂声。
【问题讨论】:
-
在尝试实现“加法/减法之前的乘法/除法”之类的规则时,您的方法会遇到麻烦。更好的方法是使用递归,就像在 Stroustrup 的书中所做的那样。
-
您描述了代码应该做什么,这很好。还请说明它的实际作用。 (您暗示
result_stack不是您在第二个循环开始时所期望的。那么它是什么?) -
我添加了你想要的。 @JaMiT
-
这个问题已经被问过很多次了。你需要一个语法、词法分析器/解析器和一个堆栈。您还应该承认,这些都是简单的算术问题,而不是非常繁重的数学问题。可能有符号数学库。除非您想自己学习如何做,否则我建议您搜索一个。
-
This gist 可能会给你更多关于算术表达式求值器实现的想法。
标签: c++ function math expression evaluate