算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式: 输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式: 在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例: 2+3*(7-4)+8/4 输出样例: 2 3 7 4 - * + 8 4 / +
本题的思路:
该题我觉得难就难在需要注意许多的测试点
1.存在小数
2.存在负数,且如果该负数没有出现在中缀表达式守,就会以(-?)的形式出现
3.同样存在带有正号的正数(有点奇怪…),以(+?)形式出现,但是输出到后缀表达式中不能带有正号
4.存在括号的嵌套
我的思路:
因为存在不止一位的数字,所以我选择将每个数字和符号之间间隔一个自己用来判断的字符(我用的是y)接下来就是大体的实现步骤,然后其余测试点的细节再在代码中添加
1.创建一个数组用来储存转换的结果,一个堆栈用来存储运算符
2.每当读到一个数字,就将该数字存入结果表达式
3.每当读到一个符号:
①如果此时的符号堆栈没有符号,就将该符号存入
②如果此时符号堆栈有符号,若优先级小于该符号,直接存入
③如果优先级大于该符号,弹出所有符号
#include<stdio.h>
#include<string.h>
int main()
{
char result[100];//用于储存结果的数组
char symbol[100];//用于储存符号的堆栈
int top = 0;//符号堆栈的栈顶指针
int length;
char s[100];//题目输入的中缀表达式
scanf("%s",&s);
length = strlen(s);
int i,j,flag,k;
for(j = 0;j < 100;j++)
result[j] = 'y';
for(j = 0,k = 0;j < length;j++){
if(s[j] == '(' || s[j] == ')')
k++;
}
i = j = flag = 0;
while(s[i] != '\0'){//当中缀表达式未结束
if(s[i] >= '0' && s[i] <= '9'){//当输入的为数字时
if((s[i+1] >= '0' && s[i+1] <= '9') || s[i+1] == '.'){//当不为个位数时
result[j++] = s[i];
}else{//当为个位数时
result[j] = s[i];
j += 2;
}
}else{//当输入的为符号时
if(top == 0 && (s[i] != '.' && j != 0)){//当栈为空,符号直接入栈
symbol[top++] = s[i];
}else if(s[i] == '*' || s[i] == '/'){//当符号为乘除时直接入栈
symbol[top++] = s[i];
}else if(s[i] == '+' || s[i] == '-'){//当符号为加减时
if(symbol[top-1] != '*' && symbol[top-1] != '/'){//当符号的优先级等于加减时
if(s[i] == '-' && s[i-1] == '('){//如果输入为(-?)时
result[j++] = '-';//向结果表达式中存入负号
flag = 1;//说明结果表达式中有负数存在
}else if(s[i] == '+' && s[i-1] == '('){//如果输入为(+?)时
flag = 2;
k++;
}else if(s[i] == '-' && j == 0){//第一个数为负数时
result[j++] = '-';
}else if(s[i] == '+' && j == 0){//第一个数为正数时
k++;
}else{//如果不是上述情况直接存入
symbol[top++] = s[i];
}
}else{//当符号的优先级高于加减时
while(top && symbol[top-1] != '('){
result[j] = symbol[top-1];
j += 2;top--;
}
symbol[top++] = s[i];
}
}else if(s[i] == '('){//当输入左括号时
symbol[top++] = s[i];
}else if(s[i] == ')'){//当输入右括号时
while(symbol[top-1] != '('){//将符号堆栈中的非(符号压入结果表达式中
result[j] = symbol[top-1];
j += 2;
top--;
}
top--;
}else if(s[i] == '.'){
result[j++] = s[i];
}
}
i++;
}
while(top){//当符号栈不为空,将其中剩余的所有符号全部压入结果表达式
result[j] = symbol[top-1];
j += 2;top--;
}
for(j = 0,i = 1;i <= length - k;){//length是表达式的长度,k是表达式中')','(','+'(正数前的正号)的数量,当i等于length-k就代表已输出完成
if(result[j] != 'y'){
printf("%c",result[j++]);
i++;
}else{
printf(" ");
j++;
}
}
}
可以注意一下
-2*(+3)
1314+25.5*12
是比较易错的测试点