21xrx.com
2025-04-01 18:37:14 Tuesday
文章检索 我的文章 写文章
C++简易计算器:字符串求值
2023-07-05 13:51:35 深夜i     23     0
C++ 简易计算器 字符串 求值

随着计算机科学技术的不断发展,编程语言的种类越来越多,每一种语言都有着它们各自的优劣势,而 C++ 作为一种被广泛使用的编程语言,其强大的功能也备受程序员们的欢迎。在本文中,我们将探讨如何使用 C++ 制作一个简易的字符串求值计算器。

首先,让我们来看看该计算器需要支持哪些基本的运算操作。在计算器中,我们很容易能想到的四则运算就应该是必须包括的:加、减、乘、除。另外,为了加强计算器的适用性,我们还要支持括号运算。现在,我们就可以开始编写代码了。

首先,我们需要定义一些基础类型。对于计算器来说,我们需要定义两个类型:Number 类型和 Operator 类型。其中,Number 表示数字类型,Operator 表示运算符类型。代码如下所示:

class Number {
public:
  Number(double number) : value(number) {}
  double getValue() const return value;
private:
  double value;
};
class Operator {
public:
  Operator(char op) : oper(op) {}
  char getOperator() const return oper;
  int getPriority() const {
    switch (oper) {
      case '+':
      case '-':
        return 1;
      case '*':
      case '/':
        return 2;
      case '(':
      case ')':
        return 0;
    }
    return -1;
  }
private:
  char oper;
};

现在,我们已经定义了基础类型,下一步是定义一个函数,用于将输入的字符串转化为由 Number 和 Operator 组成的算式,这个函数就是我们的解析函数。代码如下所示:

vector<Expression *> parse(const string& str) {
  vector<Expression *> result;
  stack<Operator *> oper_stack;
  for (int i = 0; i < str.length(); i++) {
    if (str[i] == ' ') continue;
    if (isdigit(str[i])) {
      double num = str[i] - '0';
      int j = i + 1;
      while (j < str.length() && isdigit(str[j])) {
        num = num * 10 + (str[j] - '0');
        j++;
      }
      i = j - 1;
      result.push_back(new Number(num));
    } else if (str[i] == '(') {
      oper_stack.push(new Operator(str[i]));
    } else if (str[i] == ')') {
      while (!oper_stack.empty() && oper_stack.top()->getOperator() != '(') {
        result.push_back(oper_stack.top());
        delete oper_stack.top();
        oper_stack.pop();
      }
      if (!oper_stack.empty() && oper_stack.top()->getOperator() == '(') {
        delete oper_stack.top();
        oper_stack.pop();
      }
    } else {
      Operator *oper = new Operator(str[i]);
      while (!oper_stack.empty() && oper_stack.top()->getPriority() >= oper->getPriority()) {
        result.push_back(oper_stack.top());
        oper_stack.pop();
      }
      oper_stack.push(oper);
    }
  }
  while (!oper_stack.empty()) {
    result.push_back(oper_stack.top());
    oper_stack.pop();
  }
  return result;
}

现在我们已经将输入的字符串解析成了算式,下一步是计算它们的值了。为了计算算式的值,我们需要定义一个计算函数,这个函数使用栈来存储运算结果。当遇到一个运算符时,我们就将栈中的两个数字弹出,计算它们的值,并将结果再次放入栈中。最终,栈中的唯一一个数字就是计算得到的最终结果。代码如下所示:

double calculate(vector<Expression *> vec) {
  stack<double> stk;
  for (int i = 0; i < vec.size(); i++) {
    if (Number *num = dynamic_cast<Number *>(vec[i])) {
      stk.push(num->getValue());
    } else if (Operator *oper = dynamic_cast<Operator *>(vec[i])) {
      double operand2 = stk.top();
      stk.pop();
      double operand1 = stk.top();
      stk.pop();
      switch (oper->getOperator()) {
        case '+':
          stk.push(operand1 + operand2);
          break;
        case '-':
          stk.push(operand1 - operand2);
          break;
        case '*':
          stk.push(operand1 * operand2);
          break;
        case '/':
          stk.push(operand1 / operand2);
          break;
        default:
          break;
      }
    }
  }
  return stk.top();
}

现在,我们已经完成了计算器的所有功能,我们可以编写一个简单的 main 函数,来测试我们的计算器是否正常工作。代码如下所示:

int main() {
  string str = "20*(10+(13-5)/2)-1";
  vector<Expression *> tokens = parse(str);
  cout << calculate(tokens) << endl;
  return 0;
}

结果输出为 `369`,证明我们的简易计算器能够正确地计算一个复杂算式的值。

总结起来,使用 C++ 实现一个字符串求值计算器并不难。通过解析输入的字符串,将其转化成算式,再使用栈来计算算式的值,我们就能够实现一个基本的计算器。当然,这个计算器还比较简单,如果你想要更多复杂的功能,那么需要更多的代码来实现。但是,只要你有耐心和恒心,一定能够实现一个自己需要的、更加强大的计算器。

  
  

评论区