题目描述
输入样例1
2+3*(7-4)+8/4
输出样例1
2 3 7 4 - * + 8 4 / +
输入样例2
((2+3)*4-(8+2))/5
输出样例2
2 3 + 4 * 8 2 + - 5 /
输入样例3
1314+25.5*12
输出样例3
1314 25.5 12 * +
输入样例4
-2*(+3)
输出样例4
-2 3 *
输入样例5
123
输出样例5
123
思路
栈模拟
注意:
栈内只存放字符,数字直接输出
具体流程中提到的:“运算符是数字的”表示形如-1这类的情况
具体流程:判断当前一位是什么
1.数字:继续向后判断,直到找到不是数字的且不是小数点的 —>多位数字 和 小数
2.字符:
①+ 或 - ,需要是不是在表达式开头出现,如果是,则该“运算符是数字的”;如果前一位不是数字,且不是右括号,则运算符也是数字的;除此之外,运算符就是单纯的运算符,直接入栈即可,但要保证栈顶到栈底的运算符优先级为单调递减
②* 或 /,直接入栈,但要保证栈顶到栈底的运算符优先级为单调递减
3.左括号,直接入栈
4.右括号,弹出一对括号内的字符
AC代码
#include <bits/stdc++.h>
using namespace std;
string s;
stack<char> op; //存放字符栈
map<char, int> mp; //映射符号优先级
vector<string> res; //末尾不允许有空格,因此使用res数组将结果存储下来
int ed; //当遇到数字时,ed为指向数字最后一位的指针
int len; //表达式长度
void Init() //符号优先级初始化
{
mp['+'] = 0;
mp['-'] = 0;
mp['*'] = 1;
mp['/'] = 1;
}
bool Judge_Num(char c) //判断当前字符是否为数字
{
return c >= '0' && c <= '9';
}
bool Judge_op(char c) //判断是否为符号
{
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}
string Find_Num(int be) //寻找数字
{
while(ed < len && (Judge_Num(s[ed]) || s[ed] == '.')) ed ++; //整数或小数
return s.substr(be, ed - be);
}
string char_to_string(char c) //将运算字符映射为运算字符串,便于存放进res数组
{
if(c == '-') return "-";
if(c == '+') return "+";
if(c == '*') return "*";
if(c == '/') return "/";
}
int main()
{
Init();
getline(cin, s);
len = s.size();
for(int i = 0; i < len; i ++)
{
//如果当前一位为数字,这个判断只考虑多位数字和小数的情况
if(Judge_Num(s[i]))
{
ed = i + 1;
res.push_back(Find_Num(i));
i = ed - 1; //此时ed指向的字符不为数字,但for循环还要执行一次i++的操作,因此i = ed - 1, 在执行一次i++就变为ed了
}
//如果当前一位为字符,可能是运算符如 1+2, 或者为数字的字符如-1
else if((s[i] == '+' || s[i] == '-') && i + 1 < len && Judge_Num(s[i + 1])) //当前符号为正负号,且后面一位存在,为数字
{
if(i == 0) //正负号出现在开头, 则该符号不是运算符
{
string c = "" ;
if(s[i] == '-') c = "-"; //只输出负号,正号不输出
ed = i + 1;
res.push_back(c + Find_Num(i + 1));
i = ed - 1; //同上
}
else //正负号不在开头
{
if(!Judge_Num(s[i - 1]) && s[i - 1] != ')')
{
ed = i + 1;
string c = char_to_string(s[i]);
if(c == "-") res.push_back(c + Find_Num(i + 1)); //这里只保留负号,正号不处理,如+3处理为3
else res.push_back(Find_Num(i + 1));
i = ed - 1;
}
else
{
while(op.size() && op.top() != '(' && mp[op.top()] >= mp[s[i]])
{
res.push_back(char_to_string(op.top()));
op.pop();
}
op.push(s[i]);
}
}
}
else if(s[i] == '(') op.push('(');
else if(s[i] == ')')
{
while(op.size() && op.top() != '(')
{
res.push_back(char_to_string(op.top()));
op.pop();
}
op.pop();
}
else
{
while(op.size() && op.top() != '(' && mp[op.top()] >= mp[s[i]])
{
res.push_back(char_to_string(op.top()));
op.pop();
}
op.push(s[i]);
}
}
while(op.size())
{
res.push_back(char_to_string(op.top()));
op.pop();
}
for(int i = 0; i < res.size(); i ++)
{
if(i != res.size() - 1) cout << res[i] << " ";
else cout << res[i] << endl;
}
return 0;
}
欢迎大家批评指正!!!