CCF201803-3-URL Mapping

(1) Title:

Problem Description
  URL mapping is an important component of web frameworks such as Django, Ruby on Rails, and others. For HTTP requests sent from browsers, the URL mapping module parses the URL addresses in the request and dispatches them to the appropriate processing code. Now, please implement a simple URL mapping function.
  The configuration of the URL mapping function in this question consists of several URL mapping rules. When a request arrives, the URL mapping function will match the URL addresses in the request with these rules one by one according to the configured order. When the first completely matched rule is encountered, the match is successful, and the matched rule and matched parameters are obtained. If it cannot match any of the rules, the match fails.
  The URL address entered in this question is a path with a slash / as a separator, and it is guaranteed to start with a slash. Other legal characters include upper and lower case English letters, Arabic numerals, minus sign -, underscore _ and decimal point.. For example, /person/123/ is a valid URL address, while /person/123? is not (there is an invalid character question mark ?). Also, English letters are case sensitive, so /case/ and /CAse/ are different URL addresses.
  For URL mapping rules, also start with a slash. In addition to being a normal URL address, it can also contain parameters, including the following three types:
  String <str>: used to match a string, note that the string cannot contain slashes. For example, abcde0123.
  Integer <int>: used to match an unsigned integer consisting of all Arabic numerals. For example, 01234.
  Path <path>: used to match a string, the string can contain slashes. For example, abcd/0123/.
  All three parameters above must match a non-empty string. For brevity, the title stipulates that <str> and <int> in the rule must be preceded by a slash, followed by either a slash or the end of the rule (that is, the parameter is the last part of the rule). And <path> must be preceded by a slash, followed by the end of the rule. Neither the URL address nor the rule will have consecutive slashes.
input format
  The first line of input is two positive integers  n  and  m , which respectively represent the number of URL mapping rules and the number of URL addresses to be processed, separated by a space character.
  Lines 2 to  n +1 describe the configuration information of URL mapping rules in the order of matching. Line  i + 1 contains two strings  pi  and  ri , where  pi represents  the URL matching rule, and ri represents the  URL matching name. Both strings are non-empty and contain no space characters, separated by a space character.   Lines  n +2 to  n + m +1 describe the URL address to be processed. Line  n+1 + i  contains a string  qi representing the URL address to be processed, and the string does not contain space characters.
output format
  Input a total of  m  lines, the  i - th  line represents   the matching result of qi . If the match is successful, set the rule  p j to match  , then output the corresponding  r j . At the same time, if there are parameters in the rule, the matched parameters are output in sequence in the same line. Note that leading zeros should be removed when outputting integer parameters. Separate adjacent items with a space character. If the match fails, 404 is output.
sample input
5 4
/articles/2003/ special_case_2003
/articles/<int>/ year_archive
/articles/<int>/<int>/ month_archive
/articles/<int>/<int>/<str>/ article_detail
/static/<path> static_serve
/articles/2004/
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js
Sample output
year_archive 2004
article_detail 1985 9 aloha
404
static_serve js/jquery.js
样例说明
  对于第 1 个地址 /articles/2004/,无法匹配第 1 条规则,可以匹配第 2 条规则,参数为 2004。
  对于第 2 个地址 /articles/1985/09/aloha/,只能匹配第 4 条规则,参数依次为 1985、9(已经去掉前导零)和 aloha。
  对于第 3 个地址 /articles/hello/,无法匹配任何一条规则。
  对于第 4 个地址 /static/js/jquery.js,可以匹配最后一条规则,参数为 js/jquery.js。
数据规模和约定
  1 ≤  n ≤ 100,1 ≤  m ≤ 100。
  所有输入行的长度不超过 100 个字符(不包含换行符)。
  保证输入的规则都是合法的。

(二)题目大意:

简化题目为:给你两个字符串A和B,给出两个字符串之间判断是否能匹配的规则,判断A和B是否能匹配成功。
题目中不过是对于每一个A,都有若干个B去判断是否能匹配成功,具体细节参见题目。

(三)解题思路:

  1. 规则的相邻两项之间用‘/’分开,所以我们先把所有项分开,然后依次把两个字符串的对应项匹配即可。
  2. 分离字符串这里用字符串流处理,先把所有的‘/’变为空格,然后一个一个把各项分开。
  3. 在把‘/’变为空格的时候,要注意行末的‘/’,比如:
    /okokokok  与  /okokokok/是无法匹配成功的。同样的:/<str>/ 与/okokok也无法匹配成功。
  4. 模拟,注意细节即可。

(四)具体代码:

#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<algorithm>
#define LL unsigned long long
using namespace std;
const int maxn=101;
int cnt1[maxn],isp,sp[maxn];          //cnt1[i]--第i个字符串的项数,isp--待查询的字符串末尾是否为‘/’,sp[i]--第i个字符串末尾是否为‘/’
string str[maxn],str1[maxn],str2;     //str[i]--第i个字符串的配置信息,str1[i]--第i个映射规则,str2--当前需要被查询的字符串
string sp1[maxn][maxn],sp2[maxn];     //sp1[i]--保存第i个字符串的所有项,sp2--保存当前被查询字符串的所有项。
string is_num(string s){              //判断某一项是否为整数:是--去掉前导0并返回整数;不是--返回“-”
    LL res=0,ok=0;
    string ss="";
    int len=s.length();
    for(int i=0;i<len;i++){
        if(s[i]<'0'||s[i]>'9')return "-";
        if(ok||s[i]!='0')ss+=s[i],ok=1;
    }
    if(ss=="")ss="0";
    return ss;
}
void getinfo(string s,string s1[],int &f,int &t){       //分离并保存一个字符串的所有项,标记末尾是否为‘/’
    f=t=0; 
    int len=s.length();
    if(s[len-1]=='/')f=1;
    for(int p=0;p<len;p++){
        if(s[p]=='/')s[p]=' ';
    }
    string ss;
    stringstream in(s);
    while(in>>ss)s1[t++]=ss;
}
bool match(int t,int j,string &s){                      //判断被查询字符串与第j个规则是否能匹配
    s="";
    int p1=0,p2=0;
    while(p1<t&&p2<cnt1[j]){
        if(sp2[p1]==sp1[j][p2]);
        else if(sp1[j][p2]=="<int>"){
            string f=is_num(sp2[p1]);
            if(f=="-"){return 0;}
            s+=" "+f;
        }
        else if(sp1[j][p2]=="<str>"){s+=" "+sp2[p1];}
        else if(sp1[j][p2]=="<path>"){                 //<path>直接全部加上
            s+=" "+sp2[p1++];
            while(p1<t)s+="/"+sp2[p1++];
            if(isp)s+='/';
            return 1;
        }
        else return 0;
        p1++;p2++;
    }
    if(isp^sp[j])return 0;                            //末尾判断--同时有‘/’或同时无‘/’才能匹配
    if(p1!=t||p2!=cnt1[j])return 0;                   //完全匹配
    return 1;
}
int main(){                                           //主函数
    freopen("in.txt","r",stdin);
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        cin>>str1[i]>>str[i];
        getinfo(str1[i],sp1[i],sp[i],cnt1[i]);
    }
    for(int i=0;i<m;i++){
        string ans;
        int cnt=0;isp=0;
        cin>>str2;
        getinfo(str2,sp2,isp,cnt);
        bool ok=0;
        for(int j=0;j<n;j++){
            if(match(cnt,j,ans)){
                cout<<str[j]<<ans<<endl;;
                ok=1;break;
            }
        }
        if(!ok)cout<<404<<endl;
    }
    return 0;
}

(五)总结:

貌似还是审题不仔细?考的时候并没有考虑到末尾的‘/’,再看看题,似乎题目还说明了一下关于字符串末尾的相关规定,算是暗示吗( ̄▽ ̄)"。还是想说第三题依旧是一如既往地坑~。




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324519018&siteId=291194637