后缀表达式由于其特殊性只需要操作数栈,不需要运算符栈,每当出现运算符就说明是对前面两个操作数进行操作
#include<bits/stdc++.h>
using namespace std;
char tok[30][20];
int tok_max;
int pos=1;int main(){tok_max=0;int num1=0;for(;;){int c=getchar();if(c=='@')break;if(c=='+'||c=='-'||c=='*'||c=='/'){tok[++tok_max][0]=c;}else if(c=='.'){sprintf(tok[++tok_max],"%d",num1);num1=0;}else{num1=num1*10+(c-'0');}}
// for(int i=1;i<=tok_max;i++){
// puts(tok[i]);
// }stack<int>st;for(int i=1;i<=tok_max;i++){//操作数if(isdigit(*tok[i])){ int num2;sscanf(tok[i],"%d",&num2);st.push(num2);}//运算符else if(*tok[i]=='+'){ int num3=st.top();st.pop();int num4=st.top();st.pop();int num5=num4+num3;st.push(num5);}else if(*tok[i]=='-'){int num3=st.top();st.pop();int num4=st.top();st.pop();int num5=num4-num3;st.push(num5);}else if(*tok[i]=='*'){int num3=st.top();st.pop();int num4=st.top();st.pop();int num5=num4*num3;st.push(num5);}else if(*tok[i]=='/'){int num3=st.top();st.pop();int num4=st.top();st.pop();int num5=num4/num3;st.push(num5);}}printf("%d\n",st.top());return 0;
}
前缀表达式
前缀表达式用栈写相对麻烦,但由于运算符前置,可以方便地将其转化为二叉树,递归实现
#include<bits/stdc++.h>
using namespace std;
char tok[6000][30];
int tok_max;
int pos=1;struct TREE{double val;char op;struct TREE *l,*r;
}tr;void build_tree(struct TREE *tr){if(isdigit(*tok[pos])){sscanf(tok[pos],"%lf",&(tr->val));//tr->val=atof(tok[pos]);pos++;tr->l=NULL;tr->r=NULL;return;}else{tr->op=*tok[pos];pos++;tr->l=(struct TREE*)malloc(sizeof(struct TREE));tr->r=(struct TREE*)malloc(sizeof(struct TREE));build_tree(tr->l);build_tree(tr->r);return;}
}
/*
void x(struct TREE *tr){if(tr==NULL)return;x(tr->l);if(tr->l==NULL && tr->r==NULL){printf("%f ",tr->val);}else{printf("%c ",tr->op);}x(tr->r);
}*/double calc(struct TREE *tr){if(tr->l==NULL && tr->r==NULL){ //是操作数return tr->val;}else{if(tr->op=='+')return calc(tr->l)+calc(tr->r);if(tr->op=='-')return calc(tr->l)-calc(tr->r);if(tr->op=='*')return calc(tr->l)*calc(tr->r);if(tr->op=='/')return calc(tr->l)/calc(tr->r);}
}int main(){tok_max=1;for(;;){int num=scanf("%s",tok[tok_max]);if(num==EOF)break;tok_max++;}build_tree(&tr);//x(&tr);double ans=calc(&tr);printf("%f\n",ans);return 0;
}
PS:以上代码经常出现*tok[i]
一类的表达,因为tok[i]
可看做指向数组的指针,*tok[i]
等价于tok[i][0]
,写起来简洁易懂