题目来源:http://118.190.20.162/view.page?gpid=T71
问题描述
试题编号: | 201803-3 |
试题名称: | URL映射 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 URL 映射是诸如 Django、Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件。对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 URL 地址,并将其分派给相应的处理代码。现在,请你来实现一个简单的 URL 映射功能。 输入格式 输入第一行是两个正整数 n 和 m,分别表示 URL 映射的规则条数和待处理的 URL 地址个数,中间用一个空格字符分隔。 输出格式 输入共 m 行,第 i 行表示 qi 的匹配结果。如果匹配成功,设匹配了规则 pj ,则输出对应的 rj。同时,如果规则中有参数,则在同一行内依次输出匹配后的参数。注意整数参数输出时要把前导零去掉。相邻两项之间用一个空格字符分隔。如果匹配失败,则输出 404。 样例输入 5 4 样例输出 year_archive 2004 样例说明 对于第 1 个地址 /articles/2004/,无法匹配第 1 条规则,可以匹配第 2 条规则,参数为 2004。 数据规模和约定 1 ≤ n ≤ 100,1 ≤ m ≤ 100。 |
------------------------------------------------------------
思路
比较繁琐的字符串处理模拟题
主要有两个坑点:
坑点1:rule的长度可能为0
坑点2:"/<int>/"和"/123"不能匹配,"/<int>"和"/123/" 不能匹配
------------------------------------------------------------
代码
// 思路:把每条输入的url逐条比对rule, 找到第一条match的rule解析并break
#include<iostream>
#include<string>
#include<vector>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
string p[105], r[105];
vector<string> ans; // 对应<int>/<str>/<path>的解析好的字符串
vector<string> string_split(string s)
{
int i = 0, sublen = 0;
char ch = 0;
vector<string> res;
for (i=0; i<s.size(); i++)
{
ch = s.at(i);
if (ch == '/')
{
if (sublen)
{
res.push_back(s.substr(i-sublen, sublen));
}
sublen = 0;
}
else
{
sublen++;
}
}
if (sublen)
{
res.push_back(s.substr(i-sublen, sublen));
}
return res;
}
int str2num(string s) // 字符串转数字(去掉先导0), 如果不是数字则返回-1
{
int res = 0, i = 0, multiplier = 1;
for (i=s.size()-1; i>=0; i--)
{
if (s.at(i)>='0' && s.at(i)<='9')
{
res += (s.at(i) - '0') * multiplier;
}
else
{
return -1;
}
multiplier *= 10;
}
return res;
}
string num2str(int n) // 数字转字符串
{
string res;
int tmp = 0;
while (n)
{
tmp = n % 10;
res.push_back((char)(tmp+'0'));
n /= 10;
}
reverse(res.begin(), res.end());
return res;
}
bool match(string url, string rule) // 按照rule解析url
{
vector<string> v_url = string_split(url);
vector<string> v_rule = string_split(rule);
int n1 = v_url.size(), n2 = v_rule.size(), i = 0, cnt = 0;
if (n2==0 && n1!=0) // 坑点1:rule的长度可能为0
{
return false;
}
else if (n1<n2)
{
return false;
}
else if (n1>n2)
{
if (v_rule.back() == "<path>")
{
ans.clear();
if (n2>1)
{
for (i=0; i<n2-1; i++)
{
if (v_rule.at(i) == "<int>")
{
if (str2num(v_url.at(i)) == -1)
{
return false;
}
else
{
ans.push_back(num2str(str2num(v_url.at(i))));
cnt += 1 + v_url.at(i).size();
}
}
else if (v_rule.at(i) == "<str>")
{
ans.push_back(v_url.at(i));
cnt += 1 + v_url.at(i).size();
}
else
{
if (v_url.at(i) != v_rule.at(i))
{
return false;
}
else
{
cnt += 1 + v_url.at(i).size();
}
}
}
}
ans.push_back(url.substr(cnt+1, url.size()-cnt));
}
else
{
return false;
}
}
else
{
ans.clear();
for (i=0; i<n2; i++)
{
if (v_rule.at(i) == "<int>")
{
if (str2num(v_url.at(i)) == -1)
{
return false;
}
else
{
ans.push_back(num2str(str2num(v_url.at(i))));
cnt += 1 + v_url.at(i).size();
}
}
else if (v_rule.at(i) == "<str>")
{
ans.push_back(v_url.at(i));
cnt += 1 + v_url.at(i).size();
}
else if (v_rule.at(i) == "<path>")
{
ans.push_back(url.substr(cnt+1, url.size()-cnt));
}
else
{
if (v_url.at(i) != v_rule.at(i))
{
return false;
}
else
{
cnt += 1 + v_url.at(i).size();
}
}
}
}
if ((url.at(url.size()-1) == '/' && rule.at(rule.size()-1) != '/') || (url.at(url.size()-1) != '/' && rule.at(rule.size()-1) == '/'))
{
return false; // 坑点2:"/<int>/"和"/123"不能匹配,"/<int>"和"/123/" 不能匹配
}
return true;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("201803-3.txt","r",stdin);
#endif
int i = 0, j =0;
cin >> n >> m;
string s;
bool has_match = false;
for (i=0; i<n; i++)
{
cin >> p[i] >> r[i];
}
while (m--)
{
cin >> s;
has_match = false;
for (i=0; i<n; i++)
{
if (match(s, p[i]))
{
has_match = true;
if (ans.size() == 0)
{
cout << r[i] << endl;
}
else if (ans.size() == 1)
{
cout << r[i] << " " << ans.back() << endl;
}
else
{
cout << r[i] << " ";
for (j=0; j<ans.size()-1; j++)
{
cout << ans.at(j) << " ";
}
cout << ans.back() << endl;
}
break;
}
}
if (!has_match)
{
cout << 404 << endl;
}
}
return 0;
}