CCF第十三套URL映射C语言版

根据网上的相关答案,来源已经不太清楚
本人在几处进行了一下改正,并加以注释。
(1) 题目内容、
  URL 映射是诸如 Django、Ruby on Rails 等网页框架 (web frameworks) 的一个重要组件。对于从浏览器发来的 HTTP 请求,URL 映射模块会解析请求中的 URL 地址,并将其分派给相应的处理代码。现在,请你来实现一个简单的 URL 映射功能。
  本题中 URL 映射功能的配置由若干条 URL 映射规则组成。当一个请求到达时,URL 映射功能会将请求中的 URL 地址按照配置的先后顺序逐一与这些规则进行匹配。当遇到第一条完全匹配的规则时,匹配成功,得到匹配的规则以及匹配的参数。若不能匹配任何一条规则,则匹配失败。
  本题输入的 URL 地址是以斜杠 / 作为分隔符的路径,保证以斜杠开头。其他合法字符还包括大小写英文字母、阿拉伯数字、减号 -、下划线 _ 和小数点 .。例如,/person/123/ 是一个合法的 URL 地址,而 /person/123? 则不合法(存在不合法的字符问号 ?)。另外,英文字母区分大小写,因此 /case/ 和 /CAse/ 是不同的 URL 地址。

对于 URL 映射规则,同样是以斜杠开始。除了可以是正常的 URL 地址外,还可以包含参数,有以下 3 种:

字符串 :用于匹配一段字符串,注意字符串里不能包含斜杠。例如,abcde0123。

整数 :用于匹配一个不带符号的整数,全部由阿拉伯数字组成。例如,01234。

路径 :用于匹配一段字符串,字符串可以包含斜杠。例如,abcd/0123/。
  
  以上 3 种参数都必须匹配非空的字符串。简便起见,题目规定规则中 和 前面一定是斜杠,后面要么是斜杠,要么是规则的结束(也就是该参数是规则的最后一部分)。而 的前面一定是斜杠,后面一定是规则的结束。无论是 URL 地址还是规则,都不会出现连续的斜杠。

(2) 设计思路、
该题属于对字符的操作,首先输入各项规则,再输入URL地址,若匹配规则,就输出匹配的规则数和地址参数。本题用到了四个字符型数组rule,rulename和url,还有有关输出的para数组,用u,r,l,x表示各个数组的当前元素。总的思路是,将每一个url地址与规则对照,直到找到匹配的规则,需要循环体,最外层是i(即第i条地址),里层还有j(即第j条规则)当一条地址与一个规则匹配时,总体分为三种:
1.规则的当前字符与url当前字符相同(rule[j][r]=url[i][u]),如果不符合就退出循环,flag变为0
2.规则的当前字符为<,即url映射规则是特殊情况,下一个字符就要又要分情况,第一种是i,url之后的字符应该都为‘0’到‘9’(注意:假如第一个就是‘0’,就要循环去掉0),将参数存入para,假如不满足,flag变为0,然后结束循环,直到遇到/结束,第二种是s,第三种是p。3.假如以上两种都不满足就不匹配
即使都满足,还要判断url各元素和rule各元素是否都已经判断完成,没有则flag为0.最后判断flag,是0,则错误(404),假如是1,输出个参数(rulename和para)。
(3) 源文件代码

#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#define TRUE 1
#define FALSE 0
int main()
{
 int i,j,n,m,x=0,y=0,z;
 int u=0,r=0;
 int flag=TRUE;
 scanf("%d %d",&n,&m);
 char rule[100][100];
 char rulename[100][100];  
 char url[100][100];
 char para[100][100];
 int l=0;
 for (i=0;i<n;i++)
   scanf("%s %s",rule[i],rulename[i]);
 for (j=0;j<m;j++)
   scanf("%s",url[j]);
 for (i=0;i<m;i++)//每一个指令与规则依次对照
 {
   for (j=0;j<n;j++)
   {
     u=0;
    r=0;
    l=0;//l为0
    x=0;
    flag=TRUE;
    while(r<strlen(rule[j])&&u<strlen(url[i]))
    {
       if(rule[j][r]== '<')//与第j+1个规则对照
        {
          l++;
           if(rule[j][r+1]== 'i')//假如下一个为i即int
          {
            while(url[i][u]== '0')u++;
            while(url[i][u]!='/')//直到等于/结束
            {   
                if(url[i][u]>='0'&&url[i][u]<='9')//url为整型
             {  
              para[l-1][x]=url[i][u];//满足条件,则录入para的第l行
              x++;
              u++;
               }
               else//不是整型,标志变量改变,不符合此规则,继续与下一
                个规则对照
             {
              flag=FALSE;break;//退出内循环
                }
             }
             para[l-1][x]='\0';
             if(flag== 0)
           {   
            r=0;//rule清零
            u=0;//url从头开始
            x=0;//para从头开始
            break;//不符合条件,退出外循环
           }
            else
           {
            x=0;//x置0,为录入para下一行做准备
            r=r+5;//继续与规则对照
             }
         }//都是假如等于i,判断整型
         else if(rule[j][r+1]== 's')//假如为s即str,判断字符
         {
           while(url[i][u]!='/')//与str判断结束           
           {
             para[l-1][x]=url[i][u];//u继续增加判断
             u++;
            x++;
           }
            para[l-1][x]='\0';
           if(!flag)//假如flag为0,则退出外循环
           {
           r=0;//关于url,rule,para清零 
           u=0;
           x=0;  
           break;
          }
          else
           {
           x=0;
           r=r+5;
           }
        }
         else if(rule[j][r+1]== 'p')//假如是路径
        {
         while(url[i][u]!='\0')
         {
          para[l-1][x]=url[i][u];
          u++;//url
          x++;//para
          }
          r=r+6;//path经过
         }
       }
        else if(url[i][u]==rule[j][r])//假如相等,一一对照
       {
        while(url[i][u]==rule[j][r])
         {u++;
          r++;}
        continue;//继续 
       }
       else
       {   
        flag=FALSE;
        break;
       }
    }//while循环结束 
    if(r<strlen(rule[j])||u<strlen(url[i]))//假如url进行完成,而rule没有完成或者URL已完成但是rule没有完成
        flag=FALSE;//不匹配
    if(flag)//假如flag不为0,则rulei与urlj一一对应 
     {
      printf("%s ",rulename[j]);//没有问题
      for(y=0;y<l;y++)
       printf("%s ",para[y]);
      printf("\n");
      break; 
     }
   }
    if(!flag)
      printf("404\n");
 }
return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值