zoukankan      html  css  js  c++  java
  • CCF201604-3 路径解析(解法三)(90分)


    试题编号: 201604-3
    试题名称: 路径解析
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:
    问题描述
      在操作系统中,数据通常以文件的形式存储在文件系统中。文件系统一般采用层次化的组织形式,由目录(或者文件夹)和文件构成,形成一棵树的形状。文件有内容,用于存储数据。目录是容器,可包含文件或其他目录。同一个目录下的所有文件和目录的名字各不相同,不同目录下可以有名字相同的文件或目录。
      为了指定文件系统中的某个文件,需要用路径来定位。在类 Unix 系统(Linux、Max OS X、FreeBSD等)中,路径由若干部分构成,每个部分是一个目录或者文件的名字,相邻两个部分之间用 / 符号分隔。
      有一个特殊的目录被称为根目录,是整个文件系统形成的这棵树的根节点,用一个单独的 / 符号表示。在操作系统中,有当前目录的概念,表示用户目前正在工作的目录。根据出发点可以把路径分为两类:
            绝对路径:以 / 符号开头,表示从根目录开始构建的路径。   
            相对路径:不以 / 符号开头,表示从当前目录开始构建的路径。

      例如,有一个文件系统的结构如下图所示。在这个文件系统中,有根目录 / 和其他普通目录 d1、d2、d3、d4,以及文件 f1、f2、f3、f1、f4。其中,两个 f1 是同名文件,但在不同的目录下。

      对于 d4 目录下的 f1 文件,可以用绝对路径 /d2/d4/f1 来指定。如果当前目录是 /d2/d3,这个文件也可以用相对路径 ../d4/f1 来指定,这里 .. 表示上一级目录(注意,根目录的上一级目录是它本身)。还有 . 表示本目录,例如 /d1/./f1 指定的就是 /d1/f1。注意,如果有多个连续的 / 出现,其效果等同于一个 /,例如 /d1///f1 指定的也是 /d1/f1。
      本题会给出一些路径,要求对于每个路径,给出正规化以后的形式。一个路径经过正规化操作后,其指定的文件不变,但是会变成一个不包含 . 和 .. 的绝对路径,且不包含连续多个 / 符号。如果一个路径以 / 结尾,那么它代表的一定是一个目录,正规化操作要去掉结尾的 /。若这个路径代表根目录,则正规化操作的结果是 /。若路径为空字符串,则正规化操作的结果是当前目录。
    输入格式
      第一行包含一个整数 P,表示需要进行正规化操作的路径个数。
      第二行包含一个字符串,表示当前目录。
      以下 P 行,每行包含一个字符串,表示需要进行正规化操作的路径。
    输出格式
      共 P 行,每行一个字符串,表示经过正规化操作后的路径,顺序与输入对应。
    样例输入
    7
    /d2/d3
    /d2/d4/f1
    ../d4/f1
    /d1/./f1
    /d1///f1
    /d1/
    ///
    /d1/../../d2
    样例输出
    /d2/d4/f1
    /d2/d4/f1
    /d1/f1
    /d1/f1
    /d1
    /
    /d2
    评测用例规模与约定
      1 ≤ P ≤ 10。
      文件和目录的名字只包含大小写字母、数字和小数点 .、减号 - 以及下划线 _。
      不会有文件或目录的名字是 . 或 .. ,它们具有题目描述中给出的特殊含义。
      输入的所有路径每个长度不超过 1000 个字符。
      输入的当前目录保证是一个经过正规化操作后的路径。
      对于前 30% 的测试用例,需要正规化的路径的组成部分不包含 . 和 .. 。
      对于前 60% 的测试用例,需要正规化的路径都是绝对路径。


    问题链接:CCF201604试题

    问题描述(参见上文)。

    问题分析:这是一个输入字符串处理的问题,可以有各种各样的处理方法。

    1.直接用C语言及其库函数来处理。这是最基本的最高效的(时间上)的方法,逻辑相对会复杂一些。

    2.用C++的string类有关的方法(函数)来处理。这种方法编程效率比较高。

    3.采用混合方法来处理。既使用C语言的库函数,也使用C++的类库。

    这个问题有一个陷阱,就是输入的字符串可能是空串。

    程序说明:本程序用第1中方法来实现。因为C++的cin输入字符串时,无法输入空串,而C的库函数中已经不建议使用函数gets(),所以自己编写一个读入一行的函数mygetline(),该函数可以输入空行。

    该程序有个BUG,只得了90分,希望有人帮助解决一下。

    提交后得90分的C++语言程序如下:

    /* CCF201604-3 路径解析 */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int N = 1000;
    
    char cp[N+1], s[N+1], ans[N*2+1];
    
    void mygetline(char *pc)
    {
        char c;
    
        while((c=getchar()) != '
    ' && c !=EOF)
            *pc++ = c;
        *pc = '';
    }
    
    int main()
    {
        int p;
    
        // 输入数据:整数p
        scanf("%d", &p);
        getchar();
    
        // 输入数据:当前目录
        mygetline(cp);
    
        // 输入p个路径进行正规化处理
        for(int i=1; i<=p; i++) {
            // 输入路径
            mygetline(s);
    
            // 非根路径处理
            if(s[0] != '/') {
                strcpy(ans, cp);
                strcat(ans, "/");
                strcat(ans, s);
            } else
                strcpy(ans, s);
    
            // 对输入路径进行正规化处理,并且输出结果
            char *p1, *p2, *pt;
            p1 = p2 = ans;
            while(*p2) {
                // 去除多个"/"
                if(*p2 == '/' && *(p2+1) == '/')
                    p2++;
    
                // 去除"../"
                else if(*p2 == '/' && *(p2+1) == '.' && *(p2+2) == '.' && *(p2+3) == '/') {
                    if(p1 == ans)
                        p2 += 3;
                    else {
                        pt = p1;
                        while(--pt != ans)
                            if(*pt == '/')
                                break;
                        p1 = pt;
                        p2 += 3;
                    }
    
                // 去除"./"
                } else if(*p2 == '/' && *(p2+1) == '.' && *(p2+2) == '/')
                        p2 += 2;
    
                // 去除最后的"/"
                else if(p2 != ans && *p2 == '/' && *(p2+1) == '')
                    p2++;
    
                // 去除最后的"/."
                else if(p2 != ans && *p2 == '/' && *(p2+1) == '.' && *(p2+2) == '')
                    p2 += 2;
                else {
                    *p1++ = *p2++;
                }
            }
            *p1 = '';
    
            // 输出结果
            printf("%s
    ", ans);
        }
    
        return 0;
    }


  • 相关阅读:
    mysql常用基本命令
    mysql8.0.13下载与安装图文教程
    k8s ingress 增加跨域配置
    Jenkins 备份恢复插件 thinBackup 使用
    k8s HA master 节点宕机修复
    nginx 跨域问题解决
    mongodb 3.4.24 主从复制
    k8s 线上安装 jenkins并结合 jenkinsfile 实现 helm 自动化部署
    k8s helm 运用与自建helm仓库chartmuseum
    centos6 源码安装 unzip
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564155.html
Copyright © 2011-2022 走看看