题目
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4 |
---|
输出样例:
2 3 7 4 - * + 8 4 / + |
---|
我构造的几个样例
-1+2*3-(+2)+(-1)
-1 2 3 * + 2 - -1 +
1-23+(2(-1+2*2)*5)++1
1 2 3 * - 2 -1 2 2 * + * 5 * + + 1 +
题解
比较符号的优先级有了map,会少些一些代码
其实就是细节很多
+号在最前面的时候不输出 而 符号要输出
把一个空格作为一个整体 一个空格里面的要单独看
注释很详细
#include <iostream>
#include <cstdlib>
#include <map>
using namespace std;
const int MAX_N = 100;
typedef struct SNode *SL;
struct SNode
{
char Data[MAX_N];
int Top;
} * S;
char pop()
{
S->Top--;
return S->Data[(S->Top) + 1];
}
void push(char c)
{
S->Top++;
S->Data[S->Top] = c;
}
void print()
{
static int t = 0;
if (t++ != 0)
cout << ' ';
}
int main()
{
map<char, int> p;
p['/'] = p['*'] = 1;
p['('] = p[')'] = 2;
S = (SL)malloc(sizeof(struct SNode));
S->Top = -1;
string s;
cin >> s;
for (int i = 0; i < s.size(); i++)
{
if (((i == 0 || s[i - 1] == '(') && (s[i] == '+' || s[i] == '-')) /* 判断第一位就带有符号*/
|| (s[i] == '.' || isdigit(s[i]))) //处理小数 和 多为整数 //是小数点或数字
{
//这些是一个输出
print();
if (s[i] != '+') //+号在数字前面不输出
cout << s[i];
//把数字输出完整 小数的 或是不只一位的
while (s[i + 1] == '.' || isdigit(s[i + 1]))
{
i++;
cout << s[i];
}
}
else
{
//这个空格到头了
if (s[i] == ')')
{
while (S->Top >= 0)
{
char c = pop();
if (c == '(')
break;
cout <<" "<< c;
}
}
//如果当前的 优先级比 上一个出现的符号高的话
else if (S->Top >= 0 && p[s[i]] > p[S->Data[S->Top]])
{
push(s[i]);
}
//如果当前的优先级低的话 那么前面的符号就不用管它了
// 直接全输出得了,然后再把当前的加进去
else
{
//有括号的话就是把括号里面的算完 没有的话就直接到头了
while (S->Top >= 0 && S->Data[S->Top] != '(')
{
char c = pop();
cout << ' ' << c;
}
//加进去
push(s[i]);
}
}
}
//看最后是不是还有
for (int i = S->Top; i >= 0; i--)
{
char c = pop();
cout << ' ' << c;
}
cout << endl;
return 0;
}