ZOJ 3480Duck Typing
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ 3480Duck Typing相关的知识,希望对你有一定的参考价值。
题意
1.有t组数据,输入时每组数据之间空格隔开,输出时也要求空格隔开。
2.每组都是一行begin开始,一行end结束。
3.class ClassName[:Super] 表示声明一个类型,Super值存在时,说明它继承Super类型。
4.def ClassName.Method 表示声明ClassName类型的一个方法。
5.undef ClassName.Method 表示删除该类型下该方法。
6.call ClassName.Method 表示调用该方法,如果该类型本身没有该方法,就去看它祖先是否有。
分析
可以用字符串string的函数处理,也可以用char处理(我写的姿势不是很好看,手动捂脸)。
说几个容易错的地方:。。其实姿势不同,会错的地方也不同。最口怕的是我WA在了把“oops"拼写成"opps"了QAQ。还有比如”.“不要写成”:“了!
代码
char处理
#include<cstdio> #include<cstring> struct cla { char name[50]; int mnum;//num of method char md[50][50];//method int super; } a[10050]; void read(char c,int &flag,char name[][50]) { int k=0; int len=0; int cnt=0; flag=1; if (c==‘b‘ ||c==‘e‘) flag=0;//begin/end while((c=getchar())&&c!=‘\n‘) { cnt++; if (cnt==1 && flag) { if (c==‘e‘) flag=2; else if (c==‘a‘) flag=3; else if (c==‘n‘) flag=4; } if (flag==1 && cnt>5 ||//class ClassName flag==2 && cnt>3 ||//def ClassName.Method flag==3 && cnt>4 ||//undef ClassName.Method flag==4 && cnt>5 ||//call ClassName.Method flag==5 )//class Sub:Super { name[k][len]=c; if (c==‘:‘) { name[k][len]=‘\0‘; len=-1; k=1; flag=5; } if (c==‘.‘) { name[k][len]=‘\0‘; len=-1; k=1; } len++; } } } int check(int flag,int &mp,int &fp,char name[][50],int cnum) { int defined1=0,defined2=0; int i,j; for(i=1; i<=cnum; i++) if (strcmp(a[i].name,name[0])==0) defined1= i; if (flag==1) { if(defined1) return -1; return 0; } if (flag==5) { if(defined1) return -1; else { for(i=1; i<=cnum; i++) if(strcmp(a[i].name,name[1])==0) defined1= i; if (defined1==0) return -1; return defined1; } } if (!defined1) return -1; int f=defined1,ok=0; while(f!=0&&!ok) { for(j=1; j<=a[f].mnum; j++) { if (strcmp(a[f].md[j],name[1])==0) { defined2=j; ok=1; } } mp=defined2; fp=f; if(flag==3)f=a[f].super; else f=0; } if (flag==2) { if (defined2) return -2; } else if (!defined2) return -1; return defined1; } void work(int flag,int p,int mp,int fp,char name[][50],int &cnum) { if(flag==1) { cnum++; strcpy(a[cnum].name,name[0]); a[cnum].super=0; printf("class %s\n",name[0]); } else if(flag==2) { if(p==-2) { printf("redef %s.%s\n",name[0],name[1]); } else { strcpy(a[p].md[++a[p].mnum],name[1]); printf("def %s.%s\n",a[p].name,name[1]); } } else if(flag==3) { printf("invoke %s.%s\n",a[fp].name,name[1]); } else if(flag==4) { memset(a[fp].md[mp],0,sizeof(a[fp].md[mp])); printf("undef %s.%s\n",name[0],name[1]); } else if(flag==5) { cnum++; strcpy(a[cnum].name,name[0]); a[cnum].super=p; printf("class %s:%s\n",name[0],name[1]); } } int main() { int t; scanf("%d ",&t); while(t--) { int cnum=0; int flag; //mp 是该方法在该类型的方法里是第几个 //fp 是该方法的所属的类型是第几个 int mp,fp; char c; memset(a,0,sizeof(a)); while(~(c=getchar())&&c!=‘\n‘) { char name[2][50]= {"",""}; read(c,flag,name); if(flag) { int p=check(flag,mp,fp,name,cnum); if(p==-1) printf("oops!\n"); else work(flag,p,mp,fp,name,cnum); } } printf("\n"); } return 0; }
string处理
#include <iostream> #include <cstdio> #include <map> #include <string> using namespace std; int main() { map<string,string>fa; map<string,int>cla; map<string,int>me; string s,first,cName,m,cm,super; int t; cin>>t; while (t) { cin>>s; if (s=="begin") { cla.clear(); fa.clear(); me.clear(); } else if (s=="end") { t--; cout<<"\n"; } else if (s=="class") { cin>>first; int i=first.find(‘:‘); if (i==string::npos) { if (cla[first]) cout<<"oops!\n"; else { cla[first]=1; cout<<s<<" "<<first<<"\n"; } } else { super=first.substr(i+1); first=first.erase(i); if (cla[super]==1 && cla[first]==0) { cla[first]=1; fa[first]=super; cout<<s<<" "<<first<<":"<<super<<"\n"; } else cout<<"oops!\n"; } } else if (s=="def") { cin>>first; cName=first.substr(0,first.find(‘.‘));//sub str before . if (cla[cName]==0) cout<<"oops!\n"; else { if (me[first]==1) cout<<"redef "<<first<<"\n"; else { me[first]=1; cout<<s<<" "<<first<<"\n"; } } } else if (s=="undef") { cin>>first; if (me[first]==0) cout<<"oops!\n"; else { me[first]=0; cout<<s<<" "<<first<<"\n"; } } else if (s=="call") { cin>>first; m=first.substr(first.find(‘.‘)); cName=first.substr(0,first.find(‘.‘)); cm=first; while(me[cm]==0 && (!cName.empty())) { cm=fa[cName]+m; cName=fa[cName]; } if (cName.empty()) cout<<"oops!\n"; else cout<<"invoke "<<cm<<"\n"; } } return 0; }
以上是关于ZOJ 3480Duck Typing的主要内容,如果未能解决你的问题,请参考以下文章