算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、\
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
我们先思考这样一个问题?
什么是中缀表达式什么是后缀表达式。
注意:对于 '+', '-', '*', '/',入栈之前要从栈里依次取出优先级大于等于该符号的所有元素,如果 入栈是 ')' 则输出 栈里面 '(' 到 ')'的所有元素,然后弹出 '(' 。
下面是演示:
以上是分析和操作过程,对于本题来说:
我们还需要考虑一些情况。
最后我想吐槽一句:
/*
你以为的输入
2+3*(7-4)+8/4
真实的输入
+2*(-3+2*6/9)+4/5+3
-1.233/(+332+598/9)+78/2-167
...
*/
别说了,心态崩了。
c++版。
#include <bits/stdc++.h>
using namespace std;
void to_deal(string str){
stack<char> stk;
//定义优先级
map<char,int> m;
m['+'] = m['-'] = 1;m['*'] = m['/'] = 2;m['('] = m[')'] = 3;
int index = 0;
bool flag = true;//判断是否是第一输出
while(index < str.size()){
//判断是否是操作数,如上图介绍
if((index < 1 || str[index - 1] == '(') && (str[index] == '+' || str[index] == '-') || isdigit(str[index])){
if(flag) flag = false;
else printf(" ");
if(str[index] != '+') printf("%c", str[index]);
while(str[index + 1] == '.' || isdigit(str[index + 1]))
printf("%c", str[++index]);
index++;
}else{
//操作符的情况,比较优先级,弹出优先级大于等于自己的。
if(str[index] == '(') stk.push(str[index]);
else if(str[index] == ')'){
while(!stk.empty() && stk.top() != '('){
printf(" %c", stk.top());
stk.pop();
}
stk.pop();
}else{
while(!stk.empty() && stk.top() != '(' && m[stk.top()] >= m[str[index]]){
printf(" %c", stk.top());
stk.pop();
}
stk.push(str[index]);
}
index++;
}
}
while(!stk.empty()){
printf(" %c", stk.top());
stk.pop();
}
}
int main(int argc, char const *argv[])
{
string str;
cin>>str;
to_deal(str);
return 0;
}
Python版:
ans = [];stk = []
char_dict = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3, ')': 3}
s = input()
i = 0
while i < len(s):
if (i < 1 or s[i - 1] == '(') and s[i] in ['+', '-'] or s[i].isdigit():
tmp_s = ""
if s[i] != '+':
tmp_s += s[i]
while i + 1 < len(s) and (s[i + 1] == '.' or s[i + 1].isdigit()):
tmp_s += s[i + 1]
i += 1
ans.append(tmp_s)
else:
if s[i] == '(':
stk.append(s[i])
elif s[i] == ')':
while stk and stk[-1] != '(':
ans.append(stk.pop())
stk.pop()
else:
while stk and stk[-1] != '(' and char_dict[stk[-1]] >= char_dict[s[i]]:
ans.append(stk.pop())
stk.append(s[i])
i += 1
while stk:
ans.append(stk.pop())
print(*ans)
java版
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
Stack<Character> stk = new Stack<Character>();
Map<Character, Integer> map = new HashMap<Character, Integer>();
//优先级
map.put('+', 1);map.put('-', 1);map.put('*', 2);map.put('/', 2);
map.put('(', 3);map.put(')', 3);
int index = 0;
boolean flag = true;//判断是否是第一输出
while(index < str.length()){
//判断是否是操作数,如上图介绍
if((index < 1 || str.charAt(index - 1) == '(') && (str.charAt(index) == '+' || str.charAt(index) == '-') || isdigit(str.charAt(index))){
if(flag) flag = false;
else System.out.printf(" ");
if(str.charAt(index) != '+') System.out.printf("%c", str.charAt(index));
while(index + 1 < str.length() && (str.charAt(index + 1) == '.' || isdigit(str.charAt(index + 1))))
System.out.printf("%c", str.charAt(++index));
index++;
}else{
//操作符的情况,比较优先级,弹出优先级大于等于自己的。
if(str.charAt(index) == '(') stk.push(str.charAt(index));
else if(str.charAt(index) == ')'){
while(!stk.empty() && stk.peek() != '('){
System.out.printf(" %c", stk.peek());
stk.pop();
}
stk.pop();
}else{
while(!stk.empty() && stk.peek() != '(' && map.get(stk.peek()) >= map.get(str.charAt(index))){
System.out.printf(" %c", stk.peek());
stk.pop();
}
stk.push(str.charAt(index));
}
index++;
}
}
while(!stk.empty()){
System.out.printf(" %c", stk.peek());
stk.pop();
}
}
static boolean isdigit(char s){
if(s == '1' || s == '2' || s == '3' || s == '4' || s == '5' || s == '6' || s == '7'
|| s == '8' || s == '9' || s == '0') {
return true;
}
return false;
}
}
---------更新于2.28 18:34