您的位置:首页 > 其它

PAT表达式转换

2017-10-29 11:27 155 查看

表达式转换(25 分)

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

输入格式:

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

输出格式:

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

输入样例:

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

输出样例:

2 3 7 4 - * + 8 4 / +

一道非常恶心的题,从中缀表达式转为后缀表达式,大体思路到不难,用到了一个单调栈,遇到数值就输出,遇到操作符进栈,维护一个操作符优先级单调递增栈,注意括号的处理,但麻烦的是因为有小数点和正负数,如何把数值和运算符从字符串里提取出来。第一次写的时候没有注意这一点,以为数值都是一位数的,结果3个格式错误,2个答案错误,格式错误是因为把本来之间没有空格的多位数中间加了空格,答案错误是因为没有注意小数点。写这个题还是挺考验代码实现能力的。

#include<stdio.h>
#include<string.h>
int isNumber(char a){
return a>='0' && a<='9';
}
//得到一个操作对象,记录在token里
int get(char* str,int start,int *nextstart,char* token){
int i,j;
if(isNumber(str[start])){ //说明是一个无符号的数
//把无符号数记录下来,注意小数点
for(i=0;isNumber(str[start+i])||str[start+i]=='.';i++){
token[i]=str[start+i];
}
token[i]=0;
*nextstart=start+i;// 下一次进行访问的位置
return 1;
//有符号数,一种情况是第一位是正负号,另一种情况是上一位为括号
}else if((str[start]=='+'||str[start]=='-') && (start==0||str[start-1]=='(')){
if(str[start]=='-'){ //输出负号
token[0]='-';
j=1;
}else{ //不输出正号
j=0;
}
//把有符号数记录下来,注意小数点
for(i=1;isNumber(str[start+i])||str[start+i]=='.';i++){
token[j++]=str[start+i];
}
token[j]=0;
*nextstart=start+i;//下一次访问的位置
return 1;
}else{
//为运算符
token[0]=str[start];
token[1]=0;
*nextstart=start+1;
}
return 0;
}
//定义优先级函数
int ope(char a){
if(a=='('){
return 1;
}else if(a=='*'||a=='/'){
return 3;
}else if(a=='+'||a=='-'){
return 2;
}
}
int main(void){
char str[100],stack[100],token[100],ans[100];
scanf("%s",&str);
int top=-1;
int next;
int i,j;
for(i=0,j=0;str[i];i=next){
int isnumber=get(str,i,&next,token);
//是数字的话直接存入数组里
if(isnumber){
for(int k=0;token[k];k++){
ans[j++]=token[k];
}
ans[j++]=' ';//用空格隔开
}else if(str[i]=='('){ //遇到'('直接压入栈中
stack[++top]='(';
}else if(str[i]==')'){ //遇到')'把括号里的所有运算符都弹出
while(stack[top]!='('){
ans[j++]=stack[top--];
ans[j++]=' ';
}
top--;//把'(' 也弹出
}else{//为普通运算符的情况
if(top==-1){//空栈直接进栈
stack[++top]=str[i];
}else if(ope(str[i])>ope(stack[top])){//把优先级比栈顶高的元素弹进栈里
stack[++top]=str[i];
}else{
while(top!=-1 && ope(str[i])<=ope(stack[top])){//如果不比栈顶运算符优先级高,弹出,直到比栈顶操作符优先级高
//或栈为空
ans[j++]=stack[top--];
ans[j++]=' ';
}
stack[++top]=str[i];//把该运算符进栈
}
}
}
//把栈中所有运算符都弹出
while(top!=-1){
ans[j++]=stack[top--];
ans[j++]=' ';
}
ans[j-1]='\0';//最后一个空格去掉
printf(ans);//输出
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT