If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.
In computer programming with object-oriented programming languages, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.
Given a chunk of code, your task is to tell the function of each statement. Each statement is a line of one of the following formats:
- begin. This is always the first statement of the code.
- end. This is always the last statement of the code.
- class ClassName[:Super]. Define a new class ClassName, with its superclass being Super if specified. If ClassNamehas been defined or Super has not been defined before, then ignore this statement and print "oops!". Otherwise, print "class ClassName[:Super]".
- def ClassName.MethodName. Define a method named MethodName in class ClassName. If ClassName has never been defined, then ignore this statement and print "oops!". If this method has already been defined before, then print "redefClassName.MethodName". Otherwise print "def ClassName.MethodName".
- undef ClassName.MethodName. If this method has not been defined or the class has not been defined, then ignore this statement and print "oops!". Otherwise, print "undef ClassName.MethodName" and this method is treat as if it has never been defined from now on.
- call ClassName.MethodName. Call the method ClassName.MethodName according the following principle. If the methodClassName.MethodName is defined, then invoke this method. If the class ClassName has superclass Super, then check its superclass recursively until the method is defined or there are no superclasses. Print the actual method invoked "invoke ActualClassName.MethodName" or ignore this statement and print "oops!".
All ClassName and MethodName are valid identifiers, namely a sequence of one or more ASCII letters, digits (these may not appear as the first character), and underscores. Both the length of the identifier and the depth of inheritance tree don't exceed 20.
Input
There are multiple test cases. The first line of input is an integer T ≈ 10 indicating the number of test cases.
Each test case is a chunk of code. There is a blank line after each test case.
Output
For each statement, output as the description says. Output a blank line after each test case.
Sample Input
3 begin class Sub:Super class Super class Sub:Super end begin class Class call Class.Method def Class.Method call Class.Method end begin class Super class Sub:Super def Super.Method call Sub.Method end
Sample Output
oops! class Super class Sub:Super class Class oops! def Class.Method invoke Class.Method class Super class Sub:Super def Super.Methodinvoke Super.Method
这题比较难的就是理解题目意思。
<pre style="word-wrap: break-word; white-space: pre-wrap;">#include<iostream> #include<algorithm> #include<string> #include<map> #include<vector> #include<cmath> #include<string.h> #include<stdlib.h> #include<cstdio> #define ll long long using namespace std; int main(){ int t; cin>>t; while(t--){ map<string,int> clas; map<string,int> method; map<string,string> super; //这个类的上一级类 string x,y; while(cin>>x&&x!="end"){ if(x=="begin") continue; cin>>y; if(x=="class"){ int i=y.find(":"); //学习.find的用法 if(i==string::npos){ //学习.find的用法 if(clas[y]==1) cout<<"oops!"<<endl; else{ clas[y]=1; cout<<"class "<<y<<endl; } } else{ string f=y.substr(0,i),l=y.substr(i+1); //学习.substr的用法 if(clas[f]==1||clas[l]==0) cout<<"oops!"<<endl; else{ clas[f]=1; super[f]=l; cout<<"class "<<y<<endl; } } } else if(x=="def"){ int i=y.find("."); string f=y.substr(0,i),l=y.substr(i+1); if(clas[f]==0) cout<<"oops!"<<endl; else if(method[y]==1) cout<<"redef "<<y<<endl; else{ cout<<"def "<<y<<endl; method[y]=1; } } else if(x=="undef"){ int i=y.find("."); string f=y.substr(0,i),l=y.substr(i+1); if(clas[f]==0||method[y]==0) cout<<"oops!"<<endl; else{ cout<<"undef "<<y<<endl; method[y]=0; } } else if(x=="call"){ int i=y.find("."); string f=y.substr(0,i),l=y.substr(i+1); if(method[y]==1) cout<<"invoke "<<y<<endl; else{ while(!f.empty()&&method[f+"."+l]==0) //这一步特别妙,学习 f=super[f]; if(!f.empty()) cout<<"invoke "<<f<<"."<<l<<endl; else cout<<"oops!"<<endl; } } } cout<<endl; } return 0; }