计算简单数学表达式的函数的实现。 (C++)
Implementation of a function that evaluates simple mathematical expressions. (C++)
我正在尝试编写一个计算简单数学表达式(只有四个运算)的函数。我使用 stack 和 vector 来做到这一点。但是堆栈操作并不像我预期的那样。我找不到原因。我对不同的解决方案持开放态度。
该函数应采用如下字符串:
"5 * 44 + 3 / 2 * 4 - 12"
并且 return 结果为双精度数。
#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”。 returning 值应为 214。
但是在第二个 for 循环之前,堆栈只包含“12 | - | 6”个值。 “+”和“220”值不存在。出现了一些我没有预料到的额外爆裂声。
stack content should be like this for this example
你的减法操作数被交换了。这是因为当您处理 +
和 -
操作的堆栈时,您正在从右到左解析等式。
以您的示例为例,当在堆栈中找到 -
时,result
为 12
。您弹出 -
,然后减去 6
,在结果中留下 6
,而结果应该是 -6
。
你应该使用
result = stod(result_stack.top()) - result;
用于减法。
您的代码中也没有针对无效方程的错误检查。
在这里回答:answer of the question
完成的代码在这里:
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <stack>
using namespace std;
string trim(const string& str)
{
size_t first = str.find_first_not_of(' ');
if (string::npos == first)
{
return str;
}
size_t last = str.find_last_not_of(' ');
return str.substr(first, (last - first + 1));
}
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, ' ');
vector<string> result_vector;
double result = 0;
for(unsigned int i = 0; i < values.size(); i++){
if(values[i] == "*"){
double mini_result = stod(result_vector.back()) * stod(values[i+1]);
result_vector.pop_back();
i++;
result_vector.push_back(to_string(mini_result));
}
else if(values[i] == "/"){
double mini_result = stod(result_vector.back()) / stod(values[i+1]);
result_vector.pop_back();
i++;
result_vector.push_back(to_string(mini_result));
}
else{
result_vector.push_back(values[i]);
}
}
auto iterator = result_vector.begin();
while(iterator != result_vector.end()){
if(*iterator == "-"){
iterator++;
result -= stod(*iterator);
}
else if(*iterator == "+"){
iterator++;
result += stod(*iterator);
}
else{
result += stod(*iterator);
}
iterator++;
}
return result;
}
int main()
{
cout<<evaluate("5 * 44 + 3 / 2 * 4 - 12");
}
我正在尝试编写一个计算简单数学表达式(只有四个运算)的函数。我使用 stack 和 vector 来做到这一点。但是堆栈操作并不像我预期的那样。我找不到原因。我对不同的解决方案持开放态度。
该函数应采用如下字符串:
"5 * 44 + 3 / 2 * 4 - 12"
并且 return 结果为双精度数。
#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”。 returning 值应为 214。
但是在第二个 for 循环之前,堆栈只包含“12 | - | 6”个值。 “+”和“220”值不存在。出现了一些我没有预料到的额外爆裂声。
stack content should be like this for this example
你的减法操作数被交换了。这是因为当您处理 +
和 -
操作的堆栈时,您正在从右到左解析等式。
以您的示例为例,当在堆栈中找到 -
时,result
为 12
。您弹出 -
,然后减去 6
,在结果中留下 6
,而结果应该是 -6
。
你应该使用
result = stod(result_stack.top()) - result;
用于减法。
您的代码中也没有针对无效方程的错误检查。
在这里回答:answer of the question
完成的代码在这里:
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <stack>
using namespace std;
string trim(const string& str)
{
size_t first = str.find_first_not_of(' ');
if (string::npos == first)
{
return str;
}
size_t last = str.find_last_not_of(' ');
return str.substr(first, (last - first + 1));
}
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, ' ');
vector<string> result_vector;
double result = 0;
for(unsigned int i = 0; i < values.size(); i++){
if(values[i] == "*"){
double mini_result = stod(result_vector.back()) * stod(values[i+1]);
result_vector.pop_back();
i++;
result_vector.push_back(to_string(mini_result));
}
else if(values[i] == "/"){
double mini_result = stod(result_vector.back()) / stod(values[i+1]);
result_vector.pop_back();
i++;
result_vector.push_back(to_string(mini_result));
}
else{
result_vector.push_back(values[i]);
}
}
auto iterator = result_vector.begin();
while(iterator != result_vector.end()){
if(*iterator == "-"){
iterator++;
result -= stod(*iterator);
}
else if(*iterator == "+"){
iterator++;
result += stod(*iterator);
}
else{
result += stod(*iterator);
}
iterator++;
}
return result;
}
int main()
{
cout<<evaluate("5 * 44 + 3 / 2 * 4 - 12");
}