算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、\
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
解题思路:
这道题的逻辑有点复杂,在解析的时候需要注意两个点:解析数字的时候需要考虑到小数的情况;在解析的时候遇到正负号需要判断这个正负号是运算符还是运算数的前缀。
解析过程如下:
1.遇到数字则直接打印
2.遇到 * / 和 ( 则直接入栈
3. 遇到+ 和 - 号 首先要判断前一个字符,如果前一个字符不是数字 并且 也不是有括号,那么这说明这个正负号是数字的前缀,这里需要分两种情况,第一种是正号不用输出,直接输出后面的数字即可;第二种情况是负号,则需要先输出负号再输出数字。如果前一个字符是数字,那么说明是运算符,遇到加减号就需要将所有栈内负号出栈,或者遇到栈顶元素是右括号,然后将加号或者减号入栈
4.遇到 )则需要将栈内负号出栈,直到栈顶元素为 ( 为止,并且左右括号不需要打印
5.解析完字符串后需要将符号栈中所有符号出栈
PS:这道题还有一个小细节,在每个对象中间需要有空格分隔,且第一个元素前和最后一个元素后不能有空格,在打印的时候需要注意一下
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <iostream>
using namespace std;
#define MAXSIZE 1010
//运算符栈
stack<char> opt;
int cnt = 1;
char arr[MAXSIZE];
int idx=0;
void printSpace(){
if(cnt == 1){
cnt++;
} else {
printf(" ");
}
}
int isDigit(char a){
if((a>='0' && a<='9') || a=='.'){
return 1;
} else {
return 0;
}
}
int main(){
char a;
while(~scanf("%c", &a)){
arr[idx++] = a;
}
int flag = 0;
for(int i=0; i<idx; i++){
if(isDigit(arr[i])){
printSpace();
while(isDigit(arr[i])){
printf("%c", arr[i++]);
}
i--;
} else { //符号
if(arr[i] == ')'){
//将符号出栈,直到遇到右括号
while(opt.top()!='('){
printSpace();
printf("%c", opt.top());
opt.pop();
}
if(opt.top()=='('){
opt.pop();
}
}
if(arr[i]=='*' || arr[i]=='/' || arr[i]=='('){
//直接入栈
opt.push(arr[i]);
if(arr[i] == '('){
flag=1;
}
}
if(arr[i]=='+' || arr[i]=='-'){
//先判断前面是否是数字,如果是就正常,不是就说明这是数字的前缀
if(!isDigit(arr[i-1]) && arr[i-1]!=')'){ //如果前面不是数字则输出并且不是左右括号
printSpace();
if(arr[i]=='-'){ //如果是减号则先输出减号
printf("%c", arr[i]);
}
//输出数字
i++; //略过加减号
while(isDigit(arr[i])){ //输出数字
printf("%c", arr[i++]);
}
i--;
continue;
}
//如果是空栈或者有左括号则入栈
if(opt.empty() || opt.top()=='('){
opt.push(arr[i]);
continue;
}
//将栈清空,或者遇到左括号
while(!opt.empty() && opt.top()!='('){
printSpace();
printf("%c", opt.top());
opt.pop();
}
//入栈
opt.push(arr[i]);
}
}
}
//最后将符号出栈
while(!opt.empty()){
printSpace();
printf("%c", opt.top());
opt.pop();
}
return 0;
}