数据结构·表达式求值

简介: 要求:用户输入表达式,代码结果输出计算的结果这里会用到<map>、<iomanip>、<stack>头文件,map用于存储操作符的优先级,stack有两个栈,一个用来存储操作数、一个用来存储操作符。PS:我给出了两种实现,一种是封装成类,一种是不进行封装

要求:用户输入表达式,代码结果输出计算的结果

这里会用到<map>、<iomanip>、<stack>头文件,map用于存储操作符的优先级,stack有两个栈,一个用来存储操作数、一个用来存储操作符。

PS:我给出了两种实现,一种是封装成类,一种是不进行封装

类实现:

#include<iostream>
#include<iomanip>
#include<stack>
#include<map>
using namespace std;
class Counter {
private:
  string s;
  stack<char>oper;//运算符栈
  stack<double>digit;//数值栈
  //利用map头文件
  //直接连接他们的优先级关系
  map<char, int>mp = { {'+',1}, {'-',1}, {'*',2}, {'/',2} };
public:
  //获得string函数
  void GetString() {
    cin >> s;
  }
  //计算函数
  void Calculate() {
    //给操作数赋值
    //由于栈的特性,这是第二个数值
    double b = digit.top();
    digit.pop();
    //第一个数值
    double a = digit.top();
    digit.pop();
    //定义计算结果
    double result;
    //定义运算符
    char c = oper.top();
    oper.pop();
    //计算
    if (c == '+')
      result = a + b;
    if (c == '-')
      result = a - b;
    if (c == '*')
      result = a * b;
    if (c == '/')
      result = a / b;
    digit.push(result);
  }
  //功能实现函数
  void func() {
    double x;//计算数字
    for (int i = 0; i < s.length(); i++) {
      //如果是数字
      if (s[i] >= '0' && s[i] <= '9') {
        x = s[i] - '0';
        int y = 0;
        for (int j = i + 1; s[j] >= '0' && s[j] <= '9'; j++) {
          x = x * 10 + s[j] - '0';
          y++;
        }
        digit.push(x);//数值入栈
        i += y;//跳跃
      }
      //如果是左括号,直接入栈
      else if (s[i] == '(')
        oper.push(s[i]);
      //如果是右括号,则必有左括号,计算到左括号为止,左括号出栈
      else if (s[i] == ')') {
        //如果还没到左括号就一直计算
        while (oper.top() != '(')
          Calculate();
        //到了左括号,左括号出栈
        oper.pop();
      }
      //如果是运算符,看它们的优先级,如果优先级小于等于栈顶元素,计算
      //如果栈空则直接入栈
      else {
        while (!oper.empty() && mp[oper.top()] >= mp[s[i]])
          Calculate();
        oper.push(s[i]);
      }
    }
    //如果还有运算符剩余,则一直计算
    while (!oper.empty())
      Calculate();
    //保留两位小数
    cout << setiosflags(ios::fixed) << setprecision(2) << digit.top() << endl;
    digit.pop();//相当于清空栈
  }
};
int main()
{
  int n;
  cout << "请输入表达式的个数:";
  cin >> n;
  while (n--) {
    cout << "输入一个表达式:" << endl;
    Counter c;
    c.GetString();
    c.func();
  }
  cout << endl;
  system("pause");
  return 0;
}

非类实现:

#include<iostream>
#include<iomanip>
#include<stack>
#include<map>
using namespace std;
stack<char>oper;//运算符栈
stack<double>digit;//数值栈
//利用map头文件
//直接连接他们的优先级关系
map<char, int>mp = { {'+',1}, {'-',1}, {'*',2}, {'/',2} };
//计算函数
void Calculate() {
  //给操作数赋值
  //由于栈的特性,这是第二个数值
  double b = digit.top();
  digit.pop();
  //第一个数值
  double a = digit.top();
  digit.pop();
  //定义计算结果
  double result;
  //定义运算符
  char c = oper.top();
  oper.pop();
  //计算
  if (c == '+')
    result = a + b;
  if (c == '-')
    result = a - b;
  if (c == '*')
    result = a * b;
  if (c == '/')
    result = a / b;
  digit.push(result);
}
//功能实现函数
void func() {
  string s;
  cin >> s;
  double x;//计算数字
  for (int i = 0; i < s.length(); i++) {
    //如果是数字
    if (s[i] >= '0' && s[i] <= '9') {
      x = s[i] - '0';
      int y = 0;
      for (int j = i + 1; s[j] >= '0' && s[j] <= '9'; j++) {
        x = x * 10 + s[j] - '0';
        y++;
      }
      digit.push(x);//数值入栈
      i += y;//跳跃
    }
    //如果是左括号,直接入栈
    else if (s[i] == '(')
      oper.push(s[i]);
    //如果是右括号,则必有左括号,计算到左括号为止,左括号出栈
    else if (s[i] == ')') {
      //如果还没到左括号就一直计算
      while (oper.top() != '(')
        Calculate();
      //到了左括号,左括号出栈
      oper.pop();
    }
    //如果是运算符,看它们的优先级,如果优先级小于等于栈顶元素,计算
    //如果栈空则直接入栈
    else {
      while (!oper.empty() && mp[oper.top()] >= mp[s[i]])
        Calculate();
      oper.push(s[i]);
    }
  }
  //如果还有运算符剩余,则一直计算
  while (!oper.empty())
    Calculate();
  //保留两位小数
  cout << setiosflags(ios::fixed) << setprecision(2) << digit.top() << endl;
  digit.pop();//相当于清空栈
}
int main()
{
  int n;
  cout << "请输入表达式的个数:";
  cin >> n;
  while (n--) {
    cout << "输入一个表达式:" << endl;
    func();
  }
  cout << endl;
  system("pause");
  return 0;
}

代码实现:873a28aec79140a18f8a811013f2ad47.png

相关文章
|
5月前
【栈和队列(1)(逆波兰表达式)】
【栈和队列(1)(逆波兰表达式)】
41 0
数据结构实验之栈与队列二:一般算术表达式转换成后缀式
数据结构实验之栈与队列二:一般算术表达式转换成后缀式
|
11月前
|
存储 算法 编译器
【霍洛维兹数据结构】栈和队列 | 动态循环队列 | 迷宫问题 | 表达式 | 多重栈&多重队列
【霍洛维兹数据结构】栈和队列 | 动态循环队列 | 迷宫问题 | 表达式 | 多重栈&多重队列
79 0
|
11天前
|
存储 算法 Java
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
前缀(波兰)表达式、中缀表达式和后缀(逆波兰)表达式的基本概念、计算机求值方法,以及如何将中缀表达式转换为后缀表达式,并提供了相应的Java代码实现和测试结果。
17 0
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
|
17天前
|
算法 Java C语言
【数据结构】后缀(逆波兰)表达式的计算以及中缀转后缀的方法
【数据结构】后缀(逆波兰)表达式的计算以及中缀转后缀的方法
20 0
|
4月前
|
C++
【洛谷 P1739】表达式括号匹配 题解(栈)
该编程题目要求检查给定的包含字母、运算符和括号的表达式是否括号匹配。输入为一行表达式,以`@`结束。如果括号匹配,输出`YES`,否则输出`NO`。样例包括一个匹配和一个不匹配的表达式。解决方案是使用栈,遇到左括号入栈,遇到右括号时判断栈是否为空,栈空则输出`NO`,否则出栈。当读到`@`时,栈空则输出`YES`,否则输出`NO`。提供的AC代码使用C++实现,通过`stack`处理括号匹配。
59 0
|
4月前
|
算法
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
43 0
栈在求值表达式中的应用
栈在求值表达式中的应用
|
算法
数据结构第六章分讲、栈之逆波兰表达式
(ReverseNotation,RPN,或逆波兰记法),也叫(将写在之后)。
118 0