找到的答案:
代码如下:
#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;
}
链接:
#include<iostream>
#include<vector>
#include<string>
#include<cstring>
#include<ctype.h>
using namespace std;
bool legal(char *s)
{
for(int i=0;i<strlen(s);i++)//如果不是合法的 URL地址返回false
if(s[i]!='/'&&s[i]!='.'&&s[i]!='-'&&s[i]!='_'&&!(isalpha(s[i])||isdigit(s[i])))
return false;
return true;
}
bool int_right(string s) //判断一个字符串是全为数字
{
for(int i=0;i<s.length();i++)
if(!isdigit(s[i]))
return false;
return true;
}
struct Rule{ //规则
vector<string>rule;//存储规则
string name;//匹配的名字
bool flag;//规则结尾是否有 / ,有则为true否则为flase
}r[105];
vector<string>url;//存储输入的url路径
vector<string>para;//存储参数
int n; //规则的个数
void init() //初始化把规则和匹配名存储在向量中
{
string tmp;
char a[110];//临时字符数组
int pos=0;
for(int i=1;i<=n;i++){
scanf("%s",a);//读入url规则
int end=strlen(a);
if(end>0&&a[end-1]=='/')
r[pos].flag=true;
else
r[pos].flag=false;
cin>>r[pos].name;//读入url匹配名
char *sp=strtok(a,"/");//以斜杠分割字符串
while(sp){
r[pos].rule.push_back(sp);
sp=strtok(NULL,"/");
}
pos++;
}
}
bool postfix;//输入的URL地址的后缀是否有 /
void match(char *a) //判断url地址(字符数组a存储的)是否匹配已有的规则
{
url.clear();//清空存储url的向量
char *sp=strtok(a,"/");//以斜杠分割字符串,并存储在url向量中
while(sp){
url.push_back(sp);
sp=strtok(NULL,"/");
}
//匹配
for(int i=0;i<n;i++){//匹配现有的 n 条规则
int j,k;//k表示url的段编号
para.clear();//清空存储参数的向量
bool flag=true;
for(j=0,k=0;j<r[i].rule.size()&&k<url.size();j++,k++){//每条规则被分割成了r[i].rule.size()段
string s=r[i].rule[j];
//情况一
if(s=="<int>"){
if(!int_right(url[k])){//如果它不是数字串的话,匹配失败
flag=false;
break;
}
else{//去掉前导0
string str=url[k];
for(int t=0;t<str.length()&&str[t]=='0';t++)
str.erase(t,1);
if(str!="")
para.push_back(str);
}
}
//情况二
else if(s=="<str>")
para.push_back(url[k]);
//情况三
else if(s=="<path>"){
string tmp=url[k++];
for(;k<url.size();k++)
tmp=tmp+"/"+url[k];
if(postfix)
tmp+="/";
para.push_back(tmp);
}
//情况四
else{
if(s!=url[k]){
flag=false;
break;
}
}
}
if(flag&&j>=r[i].rule.size()&&k>=url.size()&&r[i].flag==postfix){
cout<<r[i].name;
for(int ii=0;ii<para.size();ii++)
cout<<" "<<para[ii];
cout<<endl;
return;
}
}
cout<<"404"<<endl;
}
int main()
{
int m;
string s;
cin>>n>>m;
init();//初始化存储n条url规则
while(m--){
char a[110];//临时字符数组
scanf("%s",&a);//读入url地址
int end=strlen(a);
if(end>0&&a[end-1]=='/')
postfix=true;
else
postfix=false;
if(!legal(a)){//如果不是合法的url地址
cout<<"404"<<endl;
continue;
}
match(a);
}
return 0;
}