pku 1421 poj 1421 Peter's calculator

来源:互联网 发布:gsm r直放站网络优化 编辑:程序博客网 时间:2024/05/20 11:50

#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
#define BUF 55
#define inf INT_MAX

struct node{
 char name[BUF];
 int n;
 char s[101][BUF];
 bool undef;
 int val;
};

#define M 100000
node V[M];
int vn;
bool visited[M];

bool issign(char c){
 return !(c<='z' && c>='a' || c<='Z' && c>='A' || c<='9' && c>='0');
}
bool judge(char *s,int i,int ti){
 if( ti==0 ) return false;
 if( !issign(s[i]) ) {
  if( !issign(s[i+1]) )return false;
 }else {
  if( s[i]==':' ) return false;
 }
 return true;
}

int split(char *s ,char t[][BUF]){
 int i;
 int ti,cnt;
 for( cnt=ti=i=0;s[i];++i ){
  if(s[i]!=' ') t[cnt][ti++]=s[i];
  if( judge(s,i,ti) ) t[cnt++][ti]=0,ti=0;
 }
 return cnt;
}

int find(char *s){
 int i;
 for(i=0;i<vn;++i )
  if( strcmp(s,V[i].name)==0 )
   return i;
 return -1;
}

void record (char s[][BUF],int n){
 int t=find(s[0]);
 int pos;
 if( t!=-1 ){
  pos=t;
 }else{
  strcpy(V[vn].name,s[0]);
  pos=vn++;
 }
 V[pos].val=(-inf);
 V[pos].undef=1;
 strcpy(V[pos].s[0],"(");
 for(int i=2;i<n;++i ){
  strcpy(V[pos].s[i-1],s[i]);
 }
 strcpy(V[pos].s[n-1],")");
 V[pos].n=n;
}

void change_neg(char s[][BUF],int n){
 int i;
 for( i=0;i<n;++i ){
  if( s[i][0]=='-' ){
   if( i==0 || issign(s[i-1][0]) && s[i-1][0]!=')' )
    s[i][0]='&';
  }
 }
}

int degree(char c){
 switch(c){
 case ')': return 0;
    case '&':return 3;
 case '+':
 case '-': return 1;
 case '*': return 2; 
 case '(': return 4;
 }
 putchar(c);
 int f=0;
}

int cmptr( char c,char *optr,int tr ){
 if( tr==0 ) return 1;
 if( optr[tr-1]=='('  ){
   if(c==')') return 2;
   else return 1;
 }
 if( degree(c)>degree(optr[tr-1]) ) return 1;
 return 0;
}

int assign(char *);

int getnum( char s[BUF]){
 int ans,i;
 if( s[0]<='9' && s[0]>='0' ){
  for( ans=i=0;s[i];++i ){
   ans=ans*10+s[i]-'0';
  }
 }else {
  int t=find(s);
  if( t==-1  ){ ans=-inf; }
  else {
   if(!visited[t])
    ans=assign(V[t].name);
   else {
    if( V[t].undef ) ans=-inf;
    else ans=V[t].val;
   }
  }
 }
 return ans;
}

int calc( int b,int a,int c){
 int ans;
 if( c=='-' ) ans=a-b;
 else if(c=='+') ans=a+b;
 else if(c=='*') ans=a*b;
 else { int f=0;ans=1/f;}
 return ans;
}


int assign(char *name){
 int i,n,tr,nd,tt;
 int opnd[M/2];
 char optr[M],(*s)[BUF];
 
 tt=find(name);
 if( tt==-1 ) { return -inf;}
 else {
  visited[tt]=1;
  s = V[tt].s;
  n=V[tt].n;
 }
 
 bool undef;
 for( tr=nd=undef=0, i=0;i<n && !undef ;++i ){
  if( issign(s[i][0]) ) {
   int t=cmptr(s[i][0],optr,tr);
   if( t==1 ) {
    optr[tr++]=s[i][0];
   }
   else if( t==2 ) {
    --tr;
   }else {
    char tem=optr[--tr];
    if( tem=='&' ){
     opnd[nd-1]=-opnd[nd-1];
     --i;
    }else {
     int res=calc( opnd[nd-1],opnd[nd-2],tem);
     opnd[nd-2]=res;
     --nd;
     --i;
    }
   }
  }else {
   int t=getnum(s[i]);
   if( t!=-inf ) {
    opnd[nd++]=t;
   }else {
    undef=1;
   }
  }
 }
 if(!undef){
  int res=opnd[nd-1];
  V[tt].val=res;
  V[tt].undef=0;
  return res;
 }else{
  V[tt].undef=1;
  V[tt].val=-inf;
  return -inf;
 }
}

 

void out(char *s){
 int ans;
 for( int i=0;i<vn;++i ) visited[i]=0,V[i].undef=1,V[i].val=-inf;
    ans=assign(s);
 if(ans>-inf) printf("%d/n",ans);
 else printf("UNDEF/n");
}

int main(){
 char s[205];
 char T[101][BUF];
 vn=0;
 //freopen("C://in.txt","r",stdin);
 while(gets(s)!=NULL){
  int n=split(s,T);
  if(!n) continue;
  change_neg(T,n);
  if(strcmp(T[0],"PRINT")==0){
   out(T[1]);
  }else if(strcmp(T[0],"RESET")==0){
   vn=0;
  }else {
   record(T,n);
  }
 }
 return 0;
}