表达式转换
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
知识点:将中缀表达式转化为后缀表达式:
两种情况:
(1)没有括号的中缀表达式转化为后缀表达式:
(2)带有括号的中缀表达式转化为后缀表达式:
分析:本题是带有括号的中缀表达式,需要利用第二种方式实现,模拟过程我会在代码上详解
这里说一下这道题的细节问题:
中缀表达式转换为后缀表达式:对于本题而言,细节过多,在完成表达式转换的基础上
1.需要控制空格,首尾不能出现空格
2.需要判断一位以上的数字之间不能有空格
3.需要判断小数的情况,注意之间不能有空格
4.需要判断镶嵌括号的情况,容易出现格式错误
例如:当一开始就输入多个空格会使首位出现空格
5.需要判断正负号
(1)对于正号,当出现在第一位时需直接特判(在第一位无需加括号)
未在第一位出现正号一定会在括号内,而且输出时正号要省略
(2)对于负号,当出现在第一位时需要直接特判(在第一位出现无需加括号)
未在第一位出现负号一定会在括号内,需要输出负号
(3)注意控制好空格,防止格式错误
下面是代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;
const int M=1010;
char str[M],st[M],c;
stack<char> q;
int main()
{
int i,j,k=0,l,m,n,f=0,t=0,ff=0;
cin.getline(str,110);
l=strlen(str);
for(i=0; i<l; i++)
{
if(str[i]>='0'&&str[i]<='9')///为数字时输出
{
t=1;///标记已经出现过数字
///解决当有镶嵌括号时的格式问题
if(ff==0)///特判当刚开始有镶嵌括号时防止f=1对格式的影响
{
printf("%c",str[i]);
ff=1;
f=0;
continue;
}
///解决超过一位数的问题
if(f==0)///遇到数字并且前一个也是数字或'.'输出
printf("%c",str[i]);
else ///f=1时遇到数字加空格输出,并使f=0
{
printf(" %c",str[i]);
f=0;
}
}
///解决小数问题
else if(str[i]=='.')///遇到点说明为小数直接输出
{
printf("%c",str[i]);
}
///解决第一位为正数带'+'的问题
else if(i==0&&str[i]=='+')
{
printf("%c",str[i]);
}
///解决第一位为正数带'-'的问题
else if(i==0&&str[i]=='-')
{
printf("%c",str[i]);
}
///解决非第一位为正数带'-'的问题
else if(str[i]=='('&&str[i+1]=='-')
{
///输出符号
if(t==1)///若已经出现数字,加符号时需在前面加空格
printf(" %c",str[i+1]);
else
printf("%c",str[i+1]);
q.push(str[i]);///将括号入栈
f=0;///输出数字无需加空格
i++;///跳过这个'-'
}
///解决非第一位为正数带'+'的问题
else if(str[i]=='('&&str[i+1]=='+')
{
///带正号的数字的正号可以约去
q.push(str[i]);///将括号入栈
f=1;///输入数字时需要加空格
i++;///跳过'+'
}
///当遇见左括号
else if(str[i]=='(')
{
q.push(str[i]);///放入栈中
f=1;
}
///遇见右括号
else if(str[i]==')')
{
///输出左括号到右括号之间的符号
while(q.top()!='(')
{
printf(" %c",q.top());
f=1;///当输入数字时需加空格
q.pop();///将输出的字符出栈
}
//printf("%c\n",q.top());
q.pop();///将左括号出栈
}
else
{
///当栈为空或者栈顶元素为左括号
if(q.size()==0||q.top()=='(')
{
f=1;///输入数字时需要加空格
q.push(str[i]);///将符号放入栈中
}
///当需要入栈的符号优先级大于栈顶符号优先级
else if((str[i]=='*'||str[i]=='/')&&(q.top()=='+'||q.top()=='-'))
{
f=1;///输入数字时需加括号
q.push(str[i]);///将符号入栈
}
///入栈的符号优先级小于或等于栈顶符号优先级
///栈中元素不为空且栈顶元素不是左括号
else
{
///当栈顶元素为'*'或'/'
if(q.top()=='*'||q.top()=='/')
{
f=1;///输入数字需加空格
printf(" %c",q.top());///加空格输出栈顶元素
q.pop();///将栈顶元素出栈
///出栈完看栈中元素是否为空
///此时四种情况
///(1)栈中元素为0
///(2)栈顶元素为'('
///(3)栈底元素为'+'或'-',输入符号为'*'或'/'
///(4)栈底元素为'+'或'-',输入符号为'+'或'-'
///情况一和情况二
if(q.size()==0||q.top()=='(')
{
f=1;///输出数字时需加空格
q.push(str[i]);///将符号放入栈中
}
///情况三
else if(str[i]=='*'||str[i]=='/')
{
f=1;///输出数字时需加空格
q.push(str[i]);///直接将符号入栈
}
///情况四
else if(str[i]=='+'||str[i]=='-')
{
f=1;///输出数字时需加空格
printf(" %c",q.top());///将栈顶元素加空格输出
q.pop();///栈顶元素出栈
q.push(str[i]);///将符号放入栈中
}
}
///当栈顶元素为'+'或'-'
else if(q.top()=='+'||q.top()=='-')
{
///两种情况
///(1)入栈符号为'*'或'/'
///(2)入栈符号为'+'或'-'
///情况一
if(str[i]=='*'||str[i]=='/')
{
f=1;///输出数字时需加空格
q.push(str[i]);///将符号放入栈中
}
else if(str[i]=='+'||str[i]=='-')
{
f=1;///输出数字时需加空格
printf(" %c",q.top());///输出栈顶元素
q.pop();///栈顶元素出栈
q.push(str[i]);///将符号放入栈中
}
}
}
}
}
///当栈中符号未完全出栈
while(q.size()!=0)
{
printf(" %c",q.top());///将栈中符号依次输出
q.pop();///依次出栈
}
printf("\n");
return 0;
}