CCF-201803-3-URL映射

题意:
给你n个URL规则,在给你m个待处理URL 地址,求解它们与哪个规则匹配,并输出相应的参数
题解:
把字符串拆分出来,逐一匹配。注意/com/和/com,/<str>/和/<str>,/<int>/和/<int>,/<path>/和/<path>是不同的
代码如下:

#include<bits/stdc++.h>  ///201803-3
using namespace std;
const int maxn=1e2+5;
int n,m;
struct node{
    int flag;
    string content;
    int pos;
};
string name[maxn],quS;
vector<node>vecMp[maxn],vecTmp;
bool flagA[maxn];
vector<string>ans;
void init(){
    int i;
    for (i=0;i<=100;i++)vecMp[i].clear();
    memset(flagA,0,sizeof(flagA));
}
bool checkNum(string s){
    int i,lenS;
    lenS=s.size();i=0;
    while(i<lenS){
        if(isdigit(s[i]));
        else return false;
        i++;
    }
    return true;
}
bool checkFu(char fu){
    if(isalpha(fu))return true;
    if(isdigit(fu))return true;
    if(fu=='-')return true;
    if(fu=='_')return true;
    if(fu=='.')return true;
    if(fu=='/')return true;
    return false;
}
bool check(string s){
    int i,lenS;
    lenS=s.size();
    for (i=0;i<lenS;i++){
        if(checkFu(s[i]));
        else return false;
    }
    return true;
}
void deal_1(int id,string s){
    node now;
    int i,lenS,lenT;
    bool flag;
    string tmpS,tmpS2;
    lenS=s.size();i=0;tmpS="";
    if(s[lenS-1]=='/')flagA[id]=true;
    while(i<lenS){
        while(i<lenS&&(s[i]=='/'))i++;
        if(i>=lenS)break;
        tmpS="";now.pos=i;
        while(i<lenS&&(s[i]!='/'))tmpS+=s[i],i++;
        if(tmpS=="")break;
        now.content=tmpS;
        lenT=tmpS.size();flag=false;
        if(tmpS[0]=='<'&&tmpS[lenT-1]=='>'){
           tmpS2="";
           tmpS2=tmpS.substr(1,lenT-2);
           if(tmpS2=="int")now.flag=2,flag=true;
           else if(tmpS2=="str")now.flag=4,flag=true;
           else if(tmpS2=="path")now.flag=3,flag=true;
           if(flag){
              vecMp[id].push_back(now);
              continue;
           }
        }
        now.flag=1;
        vecMp[id].push_back(now);
    }
}
void deal_2(string s){
     node now;
     int i,lenS;
     string tmpS;
     vecTmp.clear();
     lenS=s.size();i=0;tmpS="";
     flagA[n+1]=false;
     if(s[lenS-1]=='/')flagA[n+1]=true;
     while(i<lenS){
        while(i<lenS&&(s[i]=='/'))i++;
        now.pos=i;
        if(i>=lenS)break;
        tmpS="";
        while(i<lenS&&(s[i]!='/'))tmpS+=s[i],i++;
        if(tmpS=="")break;
        now.content=tmpS;
        now.flag=5;
        if(checkNum(tmpS))now.flag=6;
        vecTmp.push_back(now);
     }
}
bool match(int id){
    int i,j,k,len1,len2,lenS;
    string tmpS="";
    bool flag;
    if(flagA[id]!=flagA[n+1])return false;
    ans.clear();
    i=j=0;len1=vecMp[id].size();len2=vecTmp.size();
    for (;i<len1&&(j<len2);i++,j++){
        if(vecMp[id][i].flag==1){
           if(vecMp[id][i].content==vecTmp[j].content)continue;
           else return false;
        }
        else if(vecMp[id][i].flag==2){
           if(vecTmp[j].flag==6){
              tmpS=vecTmp[j].content;
              lenS=tmpS.size();k=0;
              while(k<lenS&&(tmpS[k]=='0'))k++;
              ans.push_back(tmpS.substr(k));
              continue;
           }
           else return false;
        }
        else if(vecMp[id][i].flag==3){
            ans.push_back(quS.substr(vecTmp[j].pos));
            i=len1;j=len2;
            break;
        }
        else if(vecMp[id][i].flag==4){
            ans.push_back(vecTmp[j].content);continue;
        }
    }
    if(i>=len1&&(j>=len2));
    else return false;
    printf("%s",name[id].c_str());
    len1=ans.size();
    for (i=0;i<len1;i++)printf(" %s",ans[i].c_str());
    printf("\n");
    return true;
}
void deal(){
    int i;
    for (i=1;i<=n;i++)if(match(i))break;
    if(i>n)printf("404\n");
}
int main(){
    int i;
    string s;
    while(cin>>n>>m){
        init();
        for (i=1;i<=n;i++){
            cin>>s>>name[i];
            deal_1(i,s);
        }
        while(m--){
            cin>>quS;
            if(!check(quS)){
                printf("404\n");continue;
            }
            deal_2(quS);
            deal();
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值