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的主要内容,如果未能解决你的问题,请参考以下文章

duck typing

为什么TypeScript中的类允许使用duck typing

Python笔记 · 鸭子类型 / Duck Typing

Python笔记 · 鸭子类型 / Duck Typing

Python笔记 · 鸭子类型 / Duck Typing

TypeScript Duck Typing,未将属性字符串显示为数字错误