zoukankan      html  css  js  c++  java
  • [算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正

      上一篇的blog地址为:http://www.cnblogs.com/life91/p/3313868.html

      这几天又参加了一个家公司的笔试题,在最后的编程题中竟然出现了去哪儿网开发的第一题,也就是简化路径值。但是这次做题后,我发现我上次写的那个简化源码有很多问题,并且在这次笔试过程中也没有答对。闲话说完了,进入正题。

       上次源码出现的BUG

      1. 将连续重复的多个’/’字符视为一个。例如,”/abac/def//////ef”->”/abac/def/ef”。

      2. 根目录的开始字符为’/’,并且根目录的上级目录以及上上级目录都是本身。例如,”/../../../”->”/”。

      3. 字符’.’作为后缀名的分割符号出现。例如,”/abc/ef.gif”->”/abc/ef.gif”

      4. 以字符’/’作为起始字符。

      上述是上次源码出现的BUG。在修正这些BUG中,将增加一个临时空间用于存储原始路径。在拷贝过程中将连续重复出现的’/’变为一个’/’,并且删除”/./”这种情况。同时检查参数路径是否合法,目前仅考虑一种情况:当’.’个数超过2个时,将退出。

     1     // preprocess.
     2     while ( index < len )
     3     {
     4         // merge duplicate character -- '/'
     5         for ( cnt = 0;
     6                 index < len && path[index] == '/';
     7                 ++index, ++cnt );
     8         if ( cnt > 0 )
     9         {
    10             tmp_path[top++] = '/';
    11         }
    12 
    13         // delete only dot
    14         for ( cnt = 0;
    15                 index < len && path[index] == '.';
    16                 ++index, ++cnt );
    17         // Case 1: delete one dot.
    18         if ( top > 0 && tmp_path[top - 1] == '/' && cnt == 1 )
    19         {
    20             ++index;
    21         }
    22         // Case 2: copy two dots.
    23         else if ( cnt == 2 )
    24         {
    25             index -= cnt;
    26         }
    27         // Case 3: if more than two dots, it is error.
    28         else if ( cnt > 2 )
    29         {
    30             fprintf( stderr, "Error.
    " );
    31             // Remember: after free memory, this function could leave.
    32             free( tmp_path ), tmp_path = NULL;
    33             free( result ), result = NULL;
    34             return NULL;
    35         }
    36 
    37         // copy other characters.
    38         while ( index < len && path[index] != '/' )
    39         {
    40             tmp_path[top++] = path[index++];
    41         }
    42     }

     

      请注意:在异常退出函数时,需要将已分配的两个内存空间释放掉,并且将原始的指针指向NULL。防止内存泄漏问题。

      在后续的处理过程中,使用栈的思想来处理。当遇到连续的两个’.’时,将栈中元素弹出。如果当栈中元素全部退出的时候,将重置top节点。

     

     1         // Case 1: the number of '.' is 2;
     2         if ( top > 0 && cnt == 2 )
     3         {
     4             --top;
     5             while ( --top > 0 && result[top] != '/' );
     6         }
     7         // Case 2: "game.gif"
     8         else if ( top > 0 && result[top - 1] != '/' && cnt == 1 )
     9         {
    10             result[top++] = '.';
    11         }
    12         // Case 3: "/../../../" -> "/"
    13         else if ( top == 0)
    14         {
    15             ++top;
    16         }            

     

      完整的源码并提供简单的测试源码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <assert.h>
      5 
      6 
      7 char *normalize_path( const char *path )
      8 {
      9     char *result    = NULL;
     10     char *tmp_path  = NULL;
     11     int top         = 0;
     12     int cnt         = 0;
     13     int index       = 0;
     14     int len         = 0;
     15 
     16     assert( path != NULL && path[index] != '' && path[index] == '/' );
     17     len = strlen( path );
     18     result = (char *) malloc( sizeof(char) * (len + 1) );
     19     assert( result != NULL );
     20 
     21     tmp_path = (char *) malloc( sizeof(char) * (len + 1) );
     22     if ( tmp_path == NULL )
     23     {
     24         free( result ), result = NULL;
     25         return NULL;
     26     }
     27 
     28     // preprocess.
     29     while ( index < len )
     30     {
     31         // merge duplicate character -- '/'
     32         for ( cnt = 0;
     33                 index < len && path[index] == '/';
     34                 ++index, ++cnt );
     35         if ( cnt > 0 )
     36         {
     37             tmp_path[top++] = '/';
     38         }
     39 
     40         // delete only dot
     41         for ( cnt = 0;
     42                 index < len && path[index] == '.';
     43                 ++index, ++cnt );
     44         // Case 1: delete one dot.
     45         if ( top > 0 && tmp_path[top - 1] == '/' && cnt == 1 )
     46         {
     47             ++index;
     48         }
     49         // Case 2: copy two dots.
     50         else if ( cnt == 2 )
     51         {
     52             index -= cnt;
     53         }
     54         // Case 3: if more than two dots, it is error.
     55         else if ( cnt > 2 )
     56         {
     57             fprintf( stderr, "Error.
    " );
     58             // Remember: after free memory, this function could leave.
     59             free( tmp_path ), tmp_path = NULL;
     60             free( result ), result = NULL;
     61             return NULL;
     62         }
     63 
     64         // copy other characters.
     65         while ( index < len && path[index] != '/' )
     66         {
     67             tmp_path[top++] = path[index++];
     68         }
     69     }
     70 
     71     // other operators.
     72     tmp_path[top] = '';
     73     len = top;
     74     for ( index = 0, top = 0; index < len; )
     75     {
     76         // copy other characters except '.'
     77         while ( index < len && tmp_path[index] != '.' )
     78         {
     79             result[top++] = tmp_path[index++];
     80         }
     81 
     82         // count of point
     83         for ( cnt = 0; index < len && tmp_path[index] == '.'; ++index, ++cnt );
     84 
     85         // Case 1: the number of '.' is 2;
     86         if ( top > 0 && cnt == 2 )
     87         {
     88             --top;
     89             while ( --top > 0 && result[top] != '/' );
     90         }
     91         // Case 2: "game.gif"
     92         else if ( top > 0 && result[top - 1] != '/' && cnt == 1 )
     93         {
     94             result[top++] = '.';
     95         }
     96         // Case 3: "/../../../" -> "/"
     97         else if ( top == 0)
     98         {
     99             ++top;
    100         }
    101 
    102     }
    103     result[top] = '';
    104 
    105     // free memory
    106     free( tmp_path ), tmp_path = NULL;
    107 
    108     return result;
    109 }
    110 
    111 void output( const char *path )
    112 {
    113     char *result = NULL;
    114 
    115     result = normalize_path( path );
    116     printf( "Original is %s
    Result is %s
    
    ", path, result );
    117     free( result ), result = NULL;
    118 
    119     free( result );
    120     result = NULL;
    121 }
    122 
    123 int main()
    124 {
    125     char *path1 = "/home/news/./../tmp/game/../";
    126     char *path2 = "/../../../abc";
    127     char *path3 = "/game/gif.big";
    128     char *path4 = "///abc//..//edf/game.f";
    129 
    130     output( path1 );
    131     output( path2 );
    132     output( path3 );
    133     output( path4 );
    134 
    135     return 0;
    136 }
    normalize_path

     

     

  • 相关阅读:
    Proj THUDBFuzz Paper Reading: The Art, Science, and Engineering of Fuzzing: A Survey
    Proj THUDBFuzz Paper Reading: A systematic review of fuzzing based on machine learning techniques
    9.3 付费代理的使用
    11.1 Charles 的使用
    第十一章 APP 的爬取
    10.2 Cookies 池的搭建
    10.1 模拟登录并爬取 GitHub
    11.5 Appium 爬取微信朋友圈
    11.4 Appium 的基本使用
    11.3 mitmdump 爬取 “得到” App 电子书信息
  • 原文地址:https://www.cnblogs.com/life91/p/3396941.html
Copyright © 2011-2022 走看看