输入一个中缀算术表达式,然后将中缀式转换成后缀式,最后对后缀式求值。

img


输入一个中缀算术表达式,然后将中缀式转换成后缀式,最后对后缀式求值。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <sstream>
#include <stack>
#include <map>
using namespace std;
string change(string s)
{
    string partS="";
    stringstream c_room;
    c_room.str("");
    stack<char> symbol;           // 操作符栈
    map<char, int> rank; // 操作符优先级
    rank['+'] = rank['-'] = 1;
    rank['*'] = rank['/'] = 2;
    char c;
    int i;
    for (i = 0; i < s.length(); i++)        // 扫描中缀式
    {
        c = s[i];
        if (c <= '9' && c >= '0') //数字直接输出
            c_room << c;
        else
        {
            c_room << ' ';
            if (c == '(')      //左括号压入
                symbol.push(c);
            else if (c == ')')      //右括号一直出栈直到遇到左括号
            {
                while (symbol.top() != '(')
                {
                    c_room << symbol.top()<<' ';
                    symbol.pop();
                }
                symbol.pop();
            }
            else
            {
                while (!symbol.empty() && rank[c] <= rank[symbol.top()])
                {   // 当前操作符优先级低于或等于栈顶操作符时不断出栈,直到优先级高于栈顶操作符
                    c_room << symbol.top()<<' ';
                    symbol.pop();
                }
                symbol.push(c);
            }
        }
    }
    c_room << ' ';
    while (!symbol.empty())
    {
        c_room << symbol.top()<<' ';
        symbol.pop();
    }
    queue<string> ans;
    while (c_room >> partS)
        ans.push(partS);
    string RE_string="";
    while (!ans.empty())
    {
        RE_string += ans.front();
        ans.pop();
        if (ans.size() != 0)
            RE_string += ' ';
    }
    return RE_string;
}

int cal(char a[])
{
    int stack[260];
    int top=0;
    int i=0,x=0,t1,t2;
    while(a[i]!='#')
    {
        if(a[i]>='0' && a[i]<='9')    {
            x=0;
            while(a[i]>='0' && a[i]<='9')
            {
                x=x*10+a[i]-'0';
                i++;
            }
            stack[++top]=x;
        }
        if(a[i]=='+')
        {
            t1=stack[top--];
            t2=stack[top--];
            stack[++top]=t1+t2;
        }
        else if(a[i]=='*')
        {
            t1=stack[top--];
            t2=stack[top--];
            stack[++top]=t1*t2;
        }
        else if(a[i]=='-')
        {
            t2=stack[top--];
            t1=stack[top--];
            stack[++top]=t1-t2;
        }
        else if(a[i]=='/')
        {
            t2=stack[top--];
            t1=stack[top--];
            stack[++top]=t1/t2;
        }
        i++;
    }
    //cout<<stack[top];
    return stack[top];
}

int main()
{
    char s[260];
    cin.getline(s,260);
    string n=change(s);
    //cout <<n<<endl;
    char p[260];
    n.copy(p,250,0);
    cout << p << endl;
    cout << cal(p) << endl;
    return 0;
}

#include <cassert>
#include <iomanip>
#include <iostream>
#include <map>
#include <sstream>
#include <stack>
#include <stdexcept>

struct Token {
  enum Type { Number, Operator, End };

  union Value {
    double f;
    char c;
  };

  Type type;
  Value value;
};

// Reads a token from an input stream. A token is a number, or +, -, *, /, (, ) #
std::istream &operator>>(std::istream &is, Token &token) {
  is >> std::ws; // ignore white spaces
  auto c = is.peek();
  if (c == EOF)
    return is;
  if (std::isdigit(c)) {
    double num;
    is >> num;
    token.type = Token::Number;
    token.value.f = num;
  } else {
    switch (c) {
    case '+':
    case '-':
    case '*':
    case '/':
    case '(':
    case ')': {
      char ch;
      is >> ch;
      token.type = Token::Operator;
      token.value.c = ch;
      break;
    }
    case '#': {
      char ch;
      is >> ch;
      token.type = Token::End;
      token.value.c = ch;
      break;
    }
    default: {
      std::ostringstream ss;
      ss << "invalid character '" << static_cast<char>(c) << "' ("
         << std::showbase << std::hex << c << ")";
      throw std::runtime_error(ss.str());
    }
    }
  }
  return is;
}

// Returns lhs op rhs, where op is +, -, *, /
double calculate(double lhs, char op, double rhs) {
  switch (op) {
  case '+':
    return lhs + rhs;
  case '-':
    return lhs - rhs;
  case '*':
    return lhs * rhs;
  case '/':
    return lhs / rhs;
  default: {
    std::ostringstream ss;
    ss << "invalid operator '" << op << "'";
    throw std::runtime_error(ss.str());
  }
  }
  std::cout << lhs << op << rhs << "\n";
}

// Calculates the result of the top operator and returns the operator character.
char calculate(std::stack<double> &numberStack,
               std::stack<char> &operatorStack) {
  auto op = operatorStack.top();
  operatorStack.pop();
  if (numberStack.size() < 2)
    throw std::runtime_error("invalid expression");
  auto rhs = numberStack.top();
  numberStack.pop();
  auto lhs = numberStack.top();
  numberStack.pop();
  auto r = calculate(lhs, op, rhs);
  numberStack.push(r);
  return op;
}

int main() {
  try {
    std::map<char, int> priorities = {{'+', 0}, {'-', 0}, {'*', 1}, {'/', 1}};
    std::stack<char> operatorStack;
    std::stack<double> numberStack;
    Token token, lastToken;
    bool end = false;
    std::ostringstream out;
    out << "后缀表达式: ";
    while (!end && (std::cin >> token)) {
      switch (token.type) {
      case Token::Number: {
        out << token.value.f << ",";
        numberStack.push(token.value.f);
        break;
      }
      case Token::Operator: {
        if (token.value.c == '(') {
          operatorStack.push('(');
        } else if (token.value.c == ')') {
          while (!operatorStack.empty() && operatorStack.top() != '(')
            out << calculate(numberStack, operatorStack);
          if (operatorStack.empty())
            throw std::runtime_error("'(' and ')' mismatched");
          operatorStack.pop();
        } else {
          while (!operatorStack.empty() && operatorStack.top() != '(' &&
                 priorities[operatorStack.top()] >= priorities[token.value.c])
            out << calculate(numberStack, operatorStack);
          if ((token.value.c == '-' || token.value.c == '+') &&
              (numberStack.empty() || (lastToken.type == Token::Operator &&
                                       lastToken.value.c == '('))) {
            out << "0,";
            numberStack.push(0);
          }
          operatorStack.push(token.value.c);
        }
        break;
      }
      case Token::End:
        while (!operatorStack.empty())
          out << calculate(numberStack, operatorStack);
        end = true;
        break;
      default:
        break;
      }
      lastToken = token;
    }
    if (!operatorStack.empty())
      throw std::runtime_error("missing '#'");
    if (numberStack.size() != 1)
      throw std::runtime_error("invalid expression");
    std::cout << out.str() << '\n';
    std::cout << "值: " << std::fixed << std::setprecision(3)
              << numberStack.top() << '\n';
  } catch (const std::exception &e) {
    std::cerr << "Error: " << e.what() << '\n';
  }
  return 0;
}
$ g++ -Wall main.cpp
$ ./a.out 
9+(3-1)*3+1/2#
后缀表达式: 9,3,1,-3,*+1,2,/+
值: 15.500
$ ./a.out 
123.678+5*(5.6+78)-78.24/2+100#
后缀表达式: 123.678,5,5.6,78,+*+78.24,2,/-100,+
值: 602.558
$ ./a.out 
-123.678+5*(-5.6+78)-78.24/2+100#
后缀表达式: 0,123.678,-5,0,5.6,-78,+*+78.24,2,/-100,+
值: 299.202

用二叉树,根是符号,左子树和右子树代表进行执行符号的表达式或值,最后一个执行的符号是主根,最后后序遍历输出就行了