CCF 201803-3URL映射

本文介绍了一种通过编程实现的URL映射解析方案,利用C++语言解析URL规则,并通过匹配算法将请求路径映射到相应的处理函数。文章详细介绍了如何处理URL中的变量部分,如整数、字符串和路径,并展示了如何判断URL的有效性和匹配规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

找到的答案:

 

URL映射

代码如下:

#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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值