1-3 表达式转换 (25分) HBU-DS 实验

it2026-09-24  12

1-3 表达式转换 (25分) HBU-DS 实验

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

~

依旧是比较坎坷的一道题。

思路

先不考虑细节,首先,大致思路是:如果遇到数字就直接输出,如果遇到符号,判断他是不是比现在栈顶的符号优先级高,如果高的话就入栈,低的话(栈里的元素优先级高),就把栈里所有比他高的符号都出栈(如果优先级相同也出栈,因为相同优先级从左至右运算)。所有应该出栈的元素出栈之后,就把当前元素入栈。

注意,‘(’ 这个优先级在栈里是最低的,而在栈外最高。

好的,现在来说细节。我遇到的问题有三个:格式,小数+非单位数(我刚开始按照整数写的,一个都过去),数字带着+ - 号。

格式:就设置一个cnt,如果第一次输出数字就直接数字,否则就空格+数字。

小数+非单位数:判断下一个是不是小数点或者数字,如果是就输出,再判断

正负号:出现正负号的地方,无非两个:这个字符串的第一个位置,以及左括号之后。设置一个last(char),存上上一个字符,每次循环先判断last是不是左括号,如果是就:如果是负号就输出符号然后continue,正号直接continue;

为了统一操作,将last的初始值设置为了左括号,以此作为开头是+ -号的补充。

代码

#include <iostream> #include <string> using namespace std; int main() { char S[25]; int top = -1; string str; cin >> str; S[++top] = '('; char last = '('; int cnt = -1; for (auto it = str.begin(); it != str.end(); it++) { if (last == '(') { last = *it; if (*it == '+') continue; if (*it == '-') { cout << "-"; continue; } } last = *it; if (*it <= '9' && *it >= '0') { if (++cnt == 0) cout << *it; else cout << " " << *it; while ((it + 1) != str.end() && (*(it + 1) <= '9' && *(it + 1) >= '0' || *(it + 1) == '.')) { it++; cout << *it; } } else if (*it == '+' || *it == '-') { if (S[top] == '(') S[++top] = *it; else { while (S[top] == '+' || S[top] == '-' || S[top] == '*' || S[top] == '/') cout << " " << S[top--]; S[++top] = *it; } } else if (*it == '*' || *it == '/') { if (S[top] == '(' || S[top] == '+' || S[top] == '-') S[++top] = *it; else { while (S[top] == '*' || S[top] == '/') cout << " " << S[top--]; S[++top] = *it; } } else if (*it == '(') S[++top] = *it; else if (*it == ')') { while (S[top] != '(') { cout << " " << S[top--]; } top--; } } while (S[top] != '(') { cout << " " << S[top--]; } }
最新回复(0)