【问题标题】:Implementation of a function that evaluates simple mathematical expressions. (C++)计算简单数学表达式的函数的实现。 (C++)
【发布时间】: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”值不存在。发生了一些我没想到的额外爆裂声。

stack content should be like this for this example

【问题讨论】:

  • 在尝试实现“加法/减法之前的乘法/除法”之类的规则时,您的方法会遇到麻烦。更好的方法是使用递归,就像在 Stroustrup 的书中所做的那样。
  • 您描述了代码应该做什么,这很好。还请说明它的实际作用。 (您暗示result_stack 不是您在第二个循环开始时所期望的。那么它是什么?)
  • 我添加了你想要的。 @JaMiT
  • 这个问题已经被问过很多次了。你需要一个语法、词法分析器/解析器和一个堆栈。您还应该承认,这些都是简单的算术问题,而不是非常繁重的数学问题。可能有符号数学库。除非您想自己学习如何做,否则我建议您搜索一个。
  • This gist 可能会给你更多关于算术表达式求值器实现的想法。

标签: c++ function math expression evaluate


【解决方案1】:

减法运算的操作数被交换。这是因为当您处理 + 和 - 操作的堆栈时,您正在从右到左解析等式。

在您的示例中,当在堆栈中找到- 时,result 是12。你弹出-,然后减去6,结果应该是-6时留下6。

你应该使用

result = stod(result_stack.top()) - result;

用于减法。

您的代码中也没有错误检查无效方程式。

【讨论】:

  • 这是真的。但是第一个循环中的操作对我来说更重要。我想知道我正在做的额外流行音乐在哪里。
【解决方案2】:

在这里回答: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");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多