该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
1、逆波兰计算的时候,计算中加括号。
2、语法树中序遍历加括号。
写了个逻辑上等同于中序遍历的东西,BNF递归解析。支持个位数数字,+-*/()。
#include
#include
#include
#include
using namespace std;
enum node_type
{
OPERATOR,
NUMBER,
};
typedef struct _node{
node_type type;
string lex;
}node;
struct _priority{
string op;
int pri;
} prioritys[] = {
"+", 1,
"-", 1,
"*", 2,
"/", 2,
};
#define N_PRI (sizeof(prioritys)/ sizeof(struct _priority))
int getLazyOp(int left, int right, vector& expr)
{
int lazy_pri = 0x7fffffff;
int in_bracket_num = 0;
int domain = left;
for (; left != right; left++)
{
if (expr[left].lex == "(")
in_bracket_num++;
else if (expr[left].lex == ")")
in_bracket_num--;
if (expr[left].type == OPERATOR && in_bracket_num == 0)
{
for (int i = 0; i < N_PRI ; i++){
if (expr[left].lex == prioritys[i].op && prioritys[i].pri <= lazy_pri)
{
domain = left;
lazy_pri = prioritys[i].pri;
break;
}
}
}
}
return domain;
}
inline bool checkBracket(int left, int right, vector& expr)
{
return expr[left].lex == "(" && expr[right].lex == ")";
}
int cal(int left, int right, vector& expr, string& rs)
{
if (left > right)
return 0;
else if (left == right)
{
rs += expr[left].lex;
return 0;
}
if (checkBracket(left, right, expr))
return cal(left + 1, right - 1, expr, rs);
int index = getLazyOp(left, right, expr);
rs += "(";
cal(left, index - 1, expr, rs);
rs += expr[index].lex;
cal(index + 1, right, expr, rs);
rs += ")";
return 0;
}
int parser(string str, vector& expr)
{
if (str == "exit")
return 1;
for (int i = 0; i < str.size(); ++i)
{
if (isdigit(str[i]))
{
expr.push_back({ NUMBER, str.substr(i, 1) });
}
else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
str[i] == '(' || str[i] == ')')
{
expr.push_back({ OPERATOR, str.substr(i, 1) });
}
}
return 0;
}
int main()
{
string rs;
vector expr;
string input;
while (cin >> input)
{
expr.clear();
rs.clear();
int ret = parser(input, expr);
if (ret == 1)
{
return 0;
}
cal(0, expr.size() - 1, expr, rs);
cout << rs << endl;
}
return 0;
}