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 表达式转换
- PAT 表达式转换
- PAT DS 3-06 表达式转换
- 3-06. 表达式转换(25)(中缀表达式转后缀表达式ZJU_PAT)
- pat Data_stucture 表达式转换-栈的应用
- 浙大PAT 3-06. 表达式转换 (解题思路)
- 表达式转换【PAT】
- 3-06. 表达式转换(25)(中缀表达式转后缀表达式ZJU_PAT)
- PAT3-06. 表达式转换
- PAT乙级 1054. 求平均值 (20) 字符串转换成浮点数相关sscanf、sprintf、atof
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- 将中缀表达式转换为后缀表达式的简便方法
- 算术表达式的转换
- LINQ to Entities 不识别方法"System.String ToString()",因此该方法无法转换为存储表达式 的解决方法
- 中序表达式转换为逆波兰表达式
- SDUT2484 算术表达式的转换
- [叩响C#之门]第3章 运算符和表达式 3.5 类型转换
- LINQ to Entities 不识别方法“System.String ToString()”,因此该方法无法转换为存储表达式。
- 栈 实现 中缀表达式 转换成 后缀表达式 并 计算
- Java项目中日期类型转换成Cron表达式