题目大意:
定义n个URL匹配规则,以及m个URL地址,询问每一个URL地址,第一个和该地址匹配的URL规则。
<int> 和 数字 匹配,但是不能带 ‘ / ’这个划线分割的东西。
<str> 和 字符串匹配,但是不能带 ‘ / ’这个划线分割的东西。
<path>和 路径匹配 , 中间可以带这个 ‘ / ’ 。
需要注意哪些点:
1.
在题目中有这样一句话。保证输入都合法,但是地址并不保证,所以要手动判断地址是否合法。
2. 如果是<int>匹配的话一定要把匹配到的前导零去掉
3. 注意文中提到过,URL规则结束 和 斜线 两个定义 , URL结束就是没有斜线,所以如果规则最后的不是<path>,
那么就算前边匹配上了,但是最后一个字符不都是斜线,也是匹配不上的。
也就是说 “ /articles/2004 “ 这个和样例中的第一条规则是匹配不上的,就因为最后的斜线。
模拟步骤:
1. 将字符串按照斜线分割,每一部分都存起来到C数组,并用sz数组记录有几个部分。
2. 将询问字符串的正确性,并将每部分存入kk数组中,等待匹配。
3. 遍历规则逐一匹配,同时注意上边的3个细节。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
int n,m;
int sz[105];
string C[105][105];
string s[105],lyt[105];
string kk[105],ans[105];
int idx_p = -1,tot_p = 0,tot_k;
bool judge_int(string s) ///判断是不是可以和<int>匹配
{
int len = s.size();
for(int i=0;i<len;i++){
if(s[i]>='0' && s[i]<='9')continue;
else return 0;
}
}
bool check(int x) ///判断当前kk里的内容可不可以和x号规则匹配
{
int len = sz[x];
for(int i=1;i<=len;i++){
if(i > tot_k)return 0;
if(C[x][i] == "<int>"){ ///匹配int
if(judge_int(kk[i])){
string tt = "";
int lenk = kk[i].size(),idx= 0; ///去前导零
for(int j = 0;j<lenk;j++){
if(kk[i][j] != '0'){idx = j;break;}
}
for(int j = idx;j<lenk;j++){
tt += kk[i][j];
}
ans[++tot_p] = tt;
continue;
}
else return 0;
}
if(C[x][i] == "<str>"){ ///匹配str
ans[++tot_p] = kk[i];
continue;
}
if(C[x][i] == "<path>"){ ///如果是path后边都匹配
idx_p = i;
return 1;
}
if(C[x][i] != kk[i])return 0 ;
}
if(tot_k != len)return 0; ///匹配完后判断一下是否长度一样
return 1;
}
bool ck(string s) ///判断地址合法性
{
int len = s.size();
for(int i=0;i<len;i++){
if((s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<='Z') || (s[i]>='0' && s[i] <='9')
|| (s[i] == '-') || (s[i] == '_') || (s[i] == '.') || (s[i] == '/') )continue;
else return 0;
}
return 1;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s[i]>>lyt[i];
string k = "";
int len = s[i].size();
int tot = 0;
for(int j=1;j<len;j++){ ///分割部分
if(s[i][j] == '/'){
C[i][++tot] = k;
k = "";
}
else{
k += s[i][j];
}
}
if(s[i][len-1] != '/')C[i][++tot] = k;
sz[i] = tot;
}
while(m--){
string ss;
cin>>ss;
idx_p = -1;
if(!ck(ss)){
cout<<404<<endl;
}
int len = ss.size();
tot_k = 0;
string k = "";
for(int j=1;j<len;j++){ ///分割查询
if(ss[j] == '/'){
kk[++tot_k] = k;
k = "";
}
else{
k += ss[j];
}
}
if(ss[len-1] != '/')kk[++tot_k] = k;
int idx = -1;
for(int i=1;i<=n;i++){ ///逐一匹配
int lb = s[i].size();
if(C[i][sz[i]] != "<path>"){ ///第三细节 (40分)
if(ss[len-1] == '/' && s[i][lb-1] != '/')
continue;
if(ss[len-1] != '/' && s[i][lb-1] == '/')
continue;
}
tot_p = 0;
if(check(i)){
idx = i;break;
}
}
if(idx == -1){
cout<<404<<endl;
}
else{
cout<<lyt[idx];
for(int i=1;i<=tot_p;i++){
cout<<" "<<ans[i];
}
int cnt = 0;
if(idx_p != -1){
cout<<" ";
for(int i=0;i<len;i++){
if(cnt >= idx_p){
cout<<ss[i];
}
if(ss[i] == '/'){
cnt++;
continue;
}
}
}
cout<<endl;
}
}
}
/*
5 5
/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/0002004/
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js
*/