问题描述
试题编号: | 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。 |
一开始的思路是先对规则做处理,根据"/"做划分,用一个结构体rule来记录结果
class rule
{
public:
string name; // 规则名称
vector content; // 划分后的每个内容 例如//abc 那么content为 abc /(末尾如果为/也要记录进content)
rule(string a, vector b) :name(a), content(b) {}
};
用一个handle函数来进行处理
void handle(string s, string name)
{
int i, j, k;
int spi;
string str;
vector content;
bool isslash = true;
if (s[s.length() - 1] != '/'){
isslash = false;
s = s + "/";
}
spi = s.find("/");
while (spi != -1) {
str = s.substr(0, spi);
s = s.substr(spi + 1, s.length());
content.push_back(str);
spi = s.find("/");
}
if (isslash)
content.push_back("/"); // 末尾如果为"/"也记录进content
rules.push_back(rule(name, content));
}
接着就是开始匹配,即每个规则的content与每个带匹配的ur进行逐个匹配,用一个循环
匹配过程中若是遇到参数
循环如下
for (i = 0; i < rules[k].content.size() && urIndex < ur.size(); i++) {
if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { // 后全为参数 可直接结束
str = ur[urIndex];
for (j = urIndex + 1; j < ur.size(); j++) { // 直接添加之后的所有路径作为参数
if (ur[j] == "/") // 若末尾是'/' 直接添加
str = str + "/";
else
str = str + "/" + ur[j];
}
result.push_back(str);
urIndex = ur.size(); // 后直接全部作为参数 urIndex指向末尾表示匹配完成
i = rules[k].content.size(); // 后直接全部作为参数 i指向末尾表示匹配完成
}
else if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { //
if (judgeNum(ur[urIndex])) { // 如果待匹配路径为数字(与匹配)
result.push_back(int_to_string(string_to_int(ur[urIndex]))); // 添加参数
urIndex++;
}
else {
ifMatch = false;
break;
}
}
else if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { //
result.push_back(ur[urIndex]); // 直接匹配 添加参数
urIndex++;
}
else {
if (rules[k].content[i] == ur[urIndex]) {
urIndex++; // 匹配路径
}
else { // 路径不匹配
ifMatch = false;
break;
}
}
}
if (urIndex != ur.size() || i
总体思路就是这样,这里要强调的是一些坑
例如规则若是为 /abc/
输入的为 /abc/1 则可以匹配,若是输入为 /abc/1/ 则匹配失败
这是题目没有讲清楚的,为了处理这种情况,所以末尾的"/"我也当成要匹配的一部分
若是 规则为/abc/
输入为 /abc/123/ 还是/abc/123 均正确 不过输出的参数分别为 123/ 与 123
代码如下
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
class rule
{
public:
string name;
vector content;
rule(string a, vector b) :name(a), content(b) {}
};
vector rules;
bool ifMatch;
int string_to_int(string s)
{
int ans;
stringstream ss(s);
ss >> ans;
return ans;
}
string int_to_string(int a)
{
stringstream ss;
ss << a;
return ss.str();
}
bool judgeNum(string s)
{
for (int i = 0; i'9' || s[i]<'0') return false;
return true;
}
void handle(string s, string name)
{
int i, j, k;
int spi;
string str;
vector content;
bool isslash = true;
if (s[s.length() - 1] != '/') {
isslash = false;
s = s + "/";
}
spi = s.find("/");
while (spi != -1) {
str = s.substr(0, spi);
s = s.substr(spi + 1, s.length());
content.push_back(str);
spi = s.find("/");
}
if (isslash)
content.push_back("/");
rules.push_back(rule(name, content));
}
vector match(int k, string url)
{
int i, j;
int spi;
string str;
bool isslash = true;
vector result;
vector ur;
if (url[url.length() - 1] != '/') {
isslash = false;
url = url + "/";
}
int urIndex = 0;
spi = url.find("/");
while (spi != -1) {
str = url.substr(0, spi);
url = url.substr(spi + 1, url.length());
ur.push_back(str);
spi = url.find("/");
}
if (isslash)
ur.push_back("/");
for (i = 0; i < rules[k].content.size() && urIndex < ur.size(); i++) {
if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { // 后面一定是结束了
str = ur[urIndex];
for (j = urIndex + 1; j < ur.size(); j++) { // 直接添加之后的所有路径作为参数
if (ur[j] == "/") // 若末尾是'/' 直接添加
str = str + "/";
else
str = str + "/" + ur[j];
}
result.push_back(str);
urIndex = ur.size(); // 后直接全部作为参数 urIndex指向末尾表示匹配完成
i = rules[k].content.size(); // 后直接全部作为参数 i指向末尾表示匹配完成
}
else if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { //
if (judgeNum(ur[urIndex])) { // 如果待匹配路径为数字(与匹配)
result.push_back(int_to_string(string_to_int(ur[urIndex]))); // 字符串转数字后再转字符串 去除0
urIndex++;
}
else {
ifMatch = false;
break;
}
}
else if (rules[k].content[i] == "" && ur[urIndex].length() != 0) { //
result.push_back(ur[urIndex]); // 直接匹配
urIndex++;
}
else {
if (rules[k].content[i] == ur[urIndex]) {
urIndex++;
}
else {
ifMatch = false;
break;
}
}
}
// 未匹配完
if (urIndex != ur.size() || i < rules[k].content.size())
{
ifMatch = false;
}
return result;
}
int main()
{
int n, m, i, j, k;
string format, name, url;
cin >> n >> m;
for (i = 0; i> format >> name;
format = format.substr(1, format.length());
handle(format, name);
}
for (i = 0; i> url;
url = url.substr(1, url.length());
// 开始逐个匹配
for (j = 0; j vec = match(j, url);
if (ifMatch) {
cout << rules[j].name;
for (int h = 0; h