题目
【题目描述】PTA(数据结构与算法题目集7-20)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
【输入格式】
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、/以及左右括号(),表达式不超过20个 字符。
【输出格式】
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾 不得有多余空格。
【输入样例】
【输出样例】
解答
问题定义
将中缀表达式转化为后缀表达式
问题分析
要完成中缀表达式到后缀表达式的转换,可以采用栈来存储操作符
操作数:直接输出到后缀表达式。
操作符:依据优先级和括号规则进行处理:
- 遇到左括号
(
时,直接压栈。
- 遇到右括号
)
时,将栈中元素弹出至后缀表达式,直到遇到左括号并将其丢弃。
- 若为普通操作符(如+,-,*,/),根据优先级规则:
- 弹出栈中优先级大于等于当前操作符的符号,并加入后缀表达式。
- 然后将当前操作符压栈。
栈清空:当扫描完整个表达式后,将栈中剩余的操作符依次弹出至后缀表达式。
操作符优先级:* / > + -
算法流程
初始化空栈和空字符串存储后缀表达式。
逐个扫描输入的中缀表达式字符:
- 若为操作数(数字):直接添加到后缀表达式。
- 若为左括号
(
:压入栈中。
- 若为右括号
)
:弹出栈中元素至后缀表达式,直到遇到左括号并丢弃左括号。
- 若为操作符:依据优先级处理栈中的元素,最后将当前操作符压栈。
扫描结束后,将栈中剩余操作符依次弹出并加入后缀表达式。
输出后缀表达式。
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#include<bits/stdc++.h>
using namespace std;
int main(){
stack<char>s;
map<char,int>m;
m['+'] = 1; m['-'] = 1;
m['*'] = 2; m['/'] = 2;
m['('] = 3; m[')'] = 3;
int flag = 0;
string str;
cin >> str;
for( int i = 0; i < str.size(); i++ )
{
if( ( ((i == 0) || str[i - 1] == '(') && (str[i] == '+' || str[i] == '-'))
|| ( str[i] >='0' && str[i] <= '9')
|| ( str[i] == '.' )
)
{
if(flag != 0 )
{
cout << ' ';
}
if( str[i] != '+')
{
cout << str[i];
}
while( (str[i+1] == '.') || (str[i + 1] >= '0' && str[i + 1] <= '9'))
{
i++;
cout << str[i];
}
flag = 1;
}
else
{
if(str[i] == ')')
{
while(!s.empty() && s.top() != '(')
{
cout << ' ' << s.top();
s.pop();
}
s.pop();
}
else if(s.empty() || m[str[i]] > m[s.top()])
{
s.push(str[i]);
}
else
{
while( !s.empty() && s.top() != '(')
{
cout << ' ' << s.top();
s.pop();
}
s.push(str[i]);
}
}
}
while(!s.empty())
{
cout << ' ' << s.top();
s.pop();
}
}
|