中缀表达式转后缀表达式_牛客题霸_牛客网 (nowcoder.com)
整体思路:
- 遇到数字,直接输出
- 遇到符号
栈为空,符号直接入栈
如果是(,直接入栈
用当前符号和栈顶符号比较优先级
当前符号>栈顶符号,符号直接入栈, 结束
当前符号<=栈顶符号, 栈顶符号出栈输入,继续比较
需要考虑:1:把栈符号都出完了 ,则栈空直接入栈 2:遇到),要一直出栈,直到遇见(为止
举例
输入2 + (4+6)/2 + 6/3
输出2 4 6 + 2 /
整体过程如下:
首先定义一个符号栈,和res
- 遇到数字2,直接输出, 此时栈为空, res为[2]
- 遇到+, 栈为空直接入栈, 栈为[+], res为[2]
- 遇到( 直接入栈, 栈为[+ (], res为[2]
- 遇到数字4直接输出 , 栈为[ + ( ], res为[ 2 4 ]
- 遇到+, 优先级低于栈顶元素,直接入栈,栈为[ + ( + ], res为[ 2 4 ]
- 遇到数字6, 直接输出, 栈为[ + ( + ], res为[ 2 4 6 ]
7. 遇到) 一直出栈,直到遇到( , 栈为[ + ], res为[ 2 4 6 +]
8. 遇到/ 比+优先级高,直接入栈
- 遇到数字2,直接输出
-
遇到+,优先级低于栈顶的/, 所以/出栈输出, 然后继续与栈顶+比较,优先级相同,我们是从左往右计算的,所以先出栈,再说
-
此时栈空了,把+入栈
-
然后遇到数字6 直接输出
-
然后遇到/,优先级大于栈顶符号,所以入栈
-
然后遇到数字3,直接输出
- 最后出栈输出
代码实践
#include <iostream>
#include <string>
#include <stack>
using namespace std;
// 比较符号优先级的
bool Priority(char ch, char topch) {
if ((ch == '*' || ch == '/') && (topch == '+' || topch == '-'))
return true;
if (topch == '(' && ch != ')')
return true;
return false;
}
// 中缀表达式 => 后缀表达式
string MiddleToEndExpr(string expr) {
string result;
stack<char> s;
for (char ch : expr) {
if (ch >= 'a' && ch <= 'z') {
result.push_back(ch);
} else {
for (;;) {
// 处理符号了
if (s.empty() || ch == '(') {
s.push(ch);
break;
}
// 比较当前符号ch和栈顶符号top的优先级
char topch = s.top();
// Priority:true ch > topch false ch <= topch
if (Priority(ch, topch)) {
s.push(ch);
break;
} else {
s.pop();
if (topch == '(') // 如果遇见),一直出栈,直到(
break;
result.push_back(topch);
}
}
}
}
// 如果符号栈还存留符号,直接输出到后缀表达式里面 + /
while (!s.empty()) {
result.push_back(s.top());
s.pop();
}
return result;
}
int main() {
std::string str;
cin >> str;
std::cout << MiddleToEndExpr(str) << std::endl;
}
// 64 位输出请用 printf("%lld")
备注
将数字全部用小写字母来代替了,如果是数字则不能用一个字符串来表示输入了,应该用字符串数组,这时输入应该改为
string input;
getline(cin, input); // 得到一行带空格的字符串
分割字符串
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::string str = "one two three four";
std::stringstream ss(str);
vector<string>res;
std::string word;
while (ss >> word) {
res.push_back(word);
}
return 0;
}