#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
用二叉树,根是符号,左子树和右子树代表进行执行符号的表达式或值,最后一个执行的符号是主根,最后后序遍历输出就行了