URL映射 201803-3 C++


一、题目

在这里插入图片描述

在这里插入图片描述

原题目链接

二、解题

1.题目

这个程序解决了一个URL映射的问题。它读入一组规则,每条规则定义了一种URL模式和它对应的名称。然后程序读入一组输入URL,并将它们与规则进行匹配。如果一个输入URL与某条规则匹配,则程序输出该规则对应的名称以及从URL中提取出的参数。如果一个输入URL与任何一条规则都不匹配,则程序输出"404"。

这个程序背后的原理是使用正则表达式来匹配URL。每条规则都定义了一个正则表达式,用于描述URL模式。程序使用正则表达式匹配函数regex_match来检查输入URL是否与规则的正则表达式匹配。如果匹配成功,函数会返回true并将匹配结果存储在一个smatch对象中。程序可以通过访问这个对象来获取匹配结果中的子匹配。

2.代码

dev c++ 5.11

#include<iostream>
#include<vector>
#include<regex>
using namespace std;
inline bool isStringDigit(const string &s){
	for(char c:s) if(c<'0'||c>'9') return 0;
	return 1;
}
int main(){
	int n,m;
	string p,r; 
	cin>>n>>m;
	vector<pair<string,regex>> rules;//存储URL规则,映射为规则名->规则的正则表达式
	vector<pair<regex,string>> trans={//转换规则 
		{regex("<int>"),"(\\d+)"},{regex("<str>"),"(\\w+)"},{regex("<path>"),"(.+)"}
	};
	while(n--){
		cin>>p>>r;
		for(auto &i:trans){
			p=regex_replace(p,i.first,i.second);
		rules.push_back({r,regex(p)});
		}
	}
	smatch result; 
	while(m--){
		cin>>p;
		for(auto &i:rules)
			if(regex_match(p,result,i.second)){
				cout<<i.first.c_str();
				for(auto i=1;i<=result.size();++i){
					p=result.str(i).c_str();
					if(p!="" && isStringDigit(p))
						cout<<' '<<stoi(p);
					else
						cout<<' '<<p.c_str(); 
				}
				puts("");
				goto loop; 
			}
		puts("404");
		loop:;
	}
	return 0;
}



3.提交结果

在这里插入图片描述

总结

1.解释

  1. vector<pair<string,regex>> rules;

这行代码定义了一个名为rules的vector变量,其中每个元素都是一个pair<string,regex>类型的对象。vector是一个动态数组,可以在运行时动态地增加或删除元素。pair<string,regex>表示一个包含两个元素的对象,第一个元素是一个string类型,第二个元素是一个regex类型。

在这个程序中,rules用来存储一组URL规则,每条规则都映射为一个规则名(字符串)和一个对应的正则表达式(regex)。程序会读入这些规则并将它们存储在rules中,然后对于每个输入的URL地址,程序会逐一匹配每条规则,如果匹配成功,则输出对应的规则名和匹配到的元组。

在上面的例子中,程序读入了5条URL规则,分别为:

/articles/2003/ special_case_2003
/articles/<int>/ year_archive
/articles/<int>/<int>/ month_archive
/articles/<int>/<int>/<str>/ article_detail
/static/<path> static_serve

程序会使用转换规则将这些URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名一起存储在rules中。

经过转换后,rules中的内容如下:

rules.push_back({regex("/articles/2003/"), "special_case_2003"});
rules.push_back({regex("/articles/(\\d+)/"), "year_archive"});
rules.push_back({regex("/articles/(\\d+)/(\\d+)/"), "month_archive"});
rules.push_back({regex("/articles/(\\d+)/(\\d+)/(\\w+)/"), "article_detail"});
rules.push_back({regex("/static/(.+)"), "static_serve"});

这就是在上面的例子中,经过转换后存储在rules中的内容。

  1. 正则表达式
vector<pair<regex,string>> trans={
	{regex("<int>"),"(\\d+)"},{regex("<str>"),"(\\w+)"},{regex("<path>"),"(.+)"}
};

这行代码中的几个正则表达式分别表示:

(\d+):匹配一个或多个数字字符。\d表示一个数字字符,+表示匹配一个或多个。
(\w+):匹配一个或多个字母、数字或下划线字符。\w表示一个字母、数字或下划线字符,+表示匹配一个或多个。
(.+):匹配一个或多个任意字符。.表示任意字符,+表示匹配一个或多个。
这些正则表达式用来将输入的URL规则转换为对应的正则表达式,以便程序能够使用正则表达式匹配来判断输入的URL地址是否符合规则。

在这个程序中,trans用来存储一组转换规则,每条规则都映射为一个正则表达式(regex)和一个对应的字符串(string)。程序会读入一组URL规则,然后使用这些转换规则将每条URL规则转换为对应的正则表达式。例如,对于URL规则中的部分,程序会使用正则表达式(\d+)来替换它。

这些转换规则用来将输入的URL规则转换为对应的正则表达式,以便程序能够使用正则表达式匹配来判断输入的URL地址是否符合规则。

  1. 举例子

例如,对于第一条URL规则/articles/2003/ special_case_2003,程序会将其拆分为规则名special_case_2003和规则内容/articles/2003/。

然后,程序会使用另一个for循环遍历trans中的每条转换规则。对于每条转换规则,程序使用regex_replace函数将URL规则内容中与转换规则的第一个元素(正则表达式)匹配的部分替换为转换规则的第二个元素(字符串)。

例如,在上面的例子中,由于URL规则内容中没有任何部分与转换规则匹配,因此经过一系列的替换操作后,URL规则内容仍然保持不变。

最后,程序使用push_back函数将转换后的正则表达式和规则名一起存储在rules中。这样,当程序需要判断输入的URL地址是否符合规则时,就可以直接使用这些存储在rules中的正则表达式进行匹配。

a.
例如,在上面的例子中,经过转换后,第一条URL规则被存储在rules中为:

rules.push_back({regex(“/articles/2003/”), “special_case_2003”});
这就是程序如何使用转换规则将这些URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名存储在rules中的过程。

对于这个例子,程序会将URL规则/articles// year_archive拆分为规则名year_archive和规则内容/articles//。

然后,程序会使用一个for循环遍历每条转换规则。对于每条转换规则,程序使用regex_replace函数将URL规则内容中与转换规则的第一个元素(正则表达式)匹配的部分替换为转换规则的第二个元素(字符串)。

b.
对于/articles/<int>/ year_archive
在这个例子中,由于URL规则内容中出现了字符串,因此它与第一条转换规则匹配。所以程序会使用regex_replace函数将URL规则内容中的字符串替换为(\d+)。

经过一系列的替换操作后,URL规则内容变为了/articles/(\d+)/。

最后,程序使用push_back函数将转换后的正则表达式和规则名一起存储在rules中。这样,当程序需要判断输入的URL地址是否符合规则时,就可以直接使用这些存储在rules中的正则表达式进行匹配。

例如,在上面的例子中,经过转换后,第二条URL规则被存储在rules中为:

rules.push_back({regex(“/articles/(\d+)/”), “year_archive”});
这就是程序如何使用转换规则将这条URL规则转换为对应的正则表达式,并将转换后的正则表达式和规则名存储在rules中的过程。

  1. 匹配过程解释

smatch result;

定义了一个名为result的smatch对象。smatch是一个标准库类型,它用于存储正则表达式匹配的结果。在这个程序中,result对象用于存储regex_match函数匹配输入URL时的结果。

当使用regex_match函数检查输入URL是否与规则的正则表达式匹配时,如果匹配成功,函数会将匹配结果存储在result对象中。然后程序可以通过访问result对象来获取匹配结果中的子匹配。

这段代码是程序的主要部分,它负责读入输入URL并将它们与规则进行匹配。下面是对这段代码中各个函数和变量的解释:

m:输入URL的数量。
cin>>p:读入一个输入URL。
for(auto &i:rules):遍历所有规则。
regex_match(p,result,i.second):使用正则表达式匹配函数regex_match检查输入URLp是否与当前规则的正则表达式i.second匹配。如果匹配,函数返回true,并将匹配结果存储在result中。
cout<<i.first.c_str():如果URL与当前规则匹配,则输出该规则对应的名称i.first。
for(auto i=1;i<=result.size();++i):遍历匹配结果中的所有子匹配。
p=result.str(i).c_str():获取第i个子匹配的字符串。
isStringDigit§:调用自定义函数isStringDigit检查子匹配字符串是否为整数。
cout<<’ ‘<<stoi§:如果子匹配字符串为整数,则使用函数stoi将其转换为整数并输出。
cout<<’ '<<p.c_str():如果子匹配字符串不是整数,则直接输出该字符串。
puts(“”):在每个URL的输出后换行。
goto loop:如果URL与任意一条规则匹配,则跳过剩余的规则并直接处理下一个URL。
puts(“404”):如果URL与任何一条规则都不匹配,则输出"404"。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第4章 MFC实用技术 93 4.1 MFC常用宏应用 94 0188 获取32位整数的低字节和高字节数据 94 0189 将两个16位数组合为一个32位数 94 4.2 MFC常用函数 94 0190 MFC常用调试函数 94 0191 判断某个句柄是否关联一个窗口 95 0192 MFC应用程序信息和管理函数 95 0193 Internet URL解析全局函数 95 4.3 MFC框架技术 96 0194 在类的定义时使其具有运行时类型识别的功能 96 0195 运行时判断某个对象是否是指定的类型 96 0196 禁止文档/视图应用程序运行时显示视图选择窗口 96 0197 多个窗口消息共享同一个消息处理函数 98 0198 遍历对话框中的子控件 99 0199 在程序中捕捉CException及其派生类的异常 100 0200 扩展消息映射宏 100 0201 THIS_FILE的含义 100 0202 为静态文本控件命名 100 0203 在基于对话框的应用程序中添加文档\视图的支持 101 0204 解析浮动状态下工具栏的父窗口 101 4.4 MFC编程技术 101 0205 根据位图资源ID获取位图大小 101 0206 将某个控件对象关联到对话框中的控件资源 102 0207 将一个全局函数指针关联到对话框类的某个方法 102 0208 修改应用程序的图标 102 0209 使用安全数组 103 0210 将子窗口的客户区域映射到父窗口中 103 0211 判断两个时间段的差距 103 0212 重新设置工程名称 103 0213 为dll文件生成lib文件 104 0214 如何将一个工程中的部分资源加到另一个工程中 104 0215 根据句柄获得窗口对象的方法 104 0216 如何共享MSDN 104 0217 从完整的文件名中去除路径 104 0218 从复合字符串中解析子串 105 0219 如何获得应用程序的完整路径 105 0220 修改对话框图标的几种方法 105 0221 将多个具有不同参数的函数赋值为同一个函数指针 105

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值