0

这是我的 C++ 作业的一部分。我需要在项目中编写三个函数。当我开始工作时,我发现了一个巨大的问题,第一个函数。

首先,程序是这样的:

  1. 打开后缀表达式文件
  2. 使用 getline 逐行读取(每一行都是一个表达式)
  3. 逐步评估表达式

我知道我需要调用函数来知道下一个操作数,然后计算中间结果。该nextOperand函数返回从输入字符串的索引 I 开始的下一个操作数(数据类型:double)的值。

这就是我现在所拥有的:

double nextOperand(const string& expr, int& i)
{
    // You can make use of the function stod(string) string-to-double,
    // and the function substring() to extract an operand from the expression:
    // Example:
    //   string myExpression = "1.5 2.3 +";
    //   int pos = 0;
    //   int len = 3;
    //   string opderand = myExpression.substr(pos, len); 
    //   double value = stod(opderand);
    stack<char> temp;
    string temp1;

    while(expr[i] != ' ' && !isOperator(expr[i]))
    {
        temp.push(expr[i]);
        i++;
    }

    while(!temp.empty())
    {
        temp1 = temp.top() + temp1;
        temp.pop();
    }
    if(temp1 != "\0")
    {
        double value = stod(temp1);
        return value;
    }
    else 
        return 0;
}

评估后缀和前缀表达式的函数尚未编程。我希望先完成此nextOperand功能才能继续。

4

2 回答 2

0

我认为您对此过于复杂了。我会使用您在函数开头的评论中关于使用该substring函数的建议。然后,您可以使用类似于第一个while循环的方法来获取第一个非操作数字符的索引。根据评论使用“1.5 2.3 +”的示例输入,您可以执行以下操作:

int j = i;
while(j < expr.size() && expr.at(j) != ' ' && !isOperator(expr.at(j))) {
        j++;
    }

j是用于跟踪操作数末尾在字符串中的位置的变量,expr对于示例输入j应该等于3

然后做:

string operand = expr.substr(i, j); 
return stod(operand);
于 2013-11-08T13:22:24.007 回答
0

请注意,以下内容不会进行任何错误检测。

GCC 4.7.3:g++ -Wall -Wextra -std=c++0x rpn-calc.cpp

#include <array>
#include <cctype>
#include <functional>
#include <iostream>
#include <sstream>
#include <stack>
#include <string>

template <typename OP>
void eval(std::stack<double>& args) {
  OP op;
  auto a2 = args.top();
  args.pop();
  auto a1 = args.top();
  args.pop();
  args.push(op(a1, a2));
}

double eval(std::istream& is, std::stack<double>& args) {
  while (is) {
    std::ws(is);
    if (std::isgraph(is.peek())) {
      double arg = 0.0;
      while (is >> arg) { args.push(arg); }
      is.clear();
      is.unget(); // may have consumed a '+' or a '-'
    }

    std::ws(is);
    if (std::isgraph(is.peek())) {
      char op = 0;
      if (is >> op) {
        switch (op) {
          case '+': eval<std::plus<double>>(args); break;
          case '*': eval<std::multiplies<double>>(args); break;
          case '-': eval<std::minus<double>>(args); break;
          case '/': eval<std::divides<double>>(args); break;
        }
      }
    }
  }
  return args.top();
}

int main() {
  std::array<std::string, 7> tests = {{
    "1.0 2.0 +",
    "1.0 2.0 *",
    "1.0 2.0 -",
    "1.0 2.0 /",
    "1.0 2.0 3.0 + +",
    "1.0 2.0 + 3.0 *",
    "-1.0 +1.0 +",
  }};

  std::stack<double> env;
  for (int i = 0; i < tests.size(); ++i) {
    std::stringstream str(tests[i]);
    std::cout << eval(str, env) << std::endl;
  }
}
于 2013-11-08T18:57:52.027 回答