上一篇的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个时,将退出。

     // preprocess.
while ( index < len )
{
// merge duplicate character -- '/'
for ( cnt = ;
index < len && path[index] == '/';
++index, ++cnt );
if ( cnt > )
{
tmp_path[top++] = '/';
} // delete only dot
for ( cnt = ;
index < len && path[index] == '.';
++index, ++cnt );
// Case 1: delete one dot.
if ( top > && tmp_path[top - ] == '/' && cnt == )
{
++index;
}
// Case 2: copy two dots.
else if ( cnt == )
{
index -= cnt;
}
// Case 3: if more than two dots, it is error.
else if ( cnt > )
{
fprintf( stderr, "Error.\n" );
// Remember: after free memory, this function could leave.
free( tmp_path ), tmp_path = NULL;
free( result ), result = NULL;
return NULL;
} // copy other characters.
while ( index < len && path[index] != '/' )
{
tmp_path[top++] = path[index++];
}
}

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

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

         // Case 1: the number of '.' is 2;
if ( top > && cnt == )
{
--top;
while ( --top > && result[top] != '/' );
}
// Case 2: "game.gif"
else if ( top > && result[top - ] != '/' && cnt == )
{
result[top++] = '.';
}
// Case 3: "/../../../" -> "/"
else if ( top == )
{
++top;
}

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

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h> char *normalize_path( const char *path )
{
char *result = NULL;
char *tmp_path = NULL;
int top = ;
int cnt = ;
int index = ;
int len = ; assert( path != NULL && path[index] != '\0' && path[index] == '/' );
len = strlen( path );
result = (char *) malloc( sizeof(char) * (len + ) );
assert( result != NULL ); tmp_path = (char *) malloc( sizeof(char) * (len + ) );
if ( tmp_path == NULL )
{
free( result ), result = NULL;
return NULL;
} // preprocess.
while ( index < len )
{
// merge duplicate character -- '/'
for ( cnt = ;
index < len && path[index] == '/';
++index, ++cnt );
if ( cnt > )
{
tmp_path[top++] = '/';
} // delete only dot
for ( cnt = ;
index < len && path[index] == '.';
++index, ++cnt );
// Case 1: delete one dot.
if ( top > && tmp_path[top - ] == '/' && cnt == )
{
++index;
}
// Case 2: copy two dots.
else if ( cnt == )
{
index -= cnt;
}
// Case 3: if more than two dots, it is error.
else if ( cnt > )
{
fprintf( stderr, "Error.\n" );
// Remember: after free memory, this function could leave.
free( tmp_path ), tmp_path = NULL;
free( result ), result = NULL;
return NULL;
} // copy other characters.
while ( index < len && path[index] != '/' )
{
tmp_path[top++] = path[index++];
}
} // other operators.
tmp_path[top] = '\0';
len = top;
for ( index = , top = ; index < len; )
{
// copy other characters except '.'
while ( index < len && tmp_path[index] != '.' )
{
result[top++] = tmp_path[index++];
} // count of point
for ( cnt = ; index < len && tmp_path[index] == '.'; ++index, ++cnt ); // Case 1: the number of '.' is 2;
if ( top > && cnt == )
{
--top;
while ( --top > && result[top] != '/' );
}
// Case 2: "game.gif"
else if ( top > && result[top - ] != '/' && cnt == )
{
result[top++] = '.';
}
// Case 3: "/../../../" -> "/"
else if ( top == )
{
++top;
} }
result[top] = '\0'; // free memory
free( tmp_path ), tmp_path = NULL; return result;
} void output( const char *path )
{
char *result = NULL; result = normalize_path( path );
printf( "Original is %s\nResult is %s\n\n", path, result );
free( result ), result = NULL; free( result );
result = NULL;
} int main()
{
char *path1 = "/home/news/./../tmp/game/../";
char *path2 = "/../../../abc";
char *path3 = "/game/gif.big";
char *path4 = "///abc//..//edf/game.f"; output( path1 );
output( path2 );
output( path3 );
output( path4 ); return ;
}

normalize_path

[算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正的更多相关文章

  1. 算法笔记_108:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科A组)试题解答

     目录 1 世纪末的星期 2 振兴中华 3 梅森素数 4 颠倒的价牌 5 三部排序 6 逆波兰表达式 7 错误票据 8 带分数 9 剪格子 10 大臣的旅费 前言:以下试题解答代码部分仅供参考,若有不 ...

  2. 算法笔记_110:第四届蓝桥杯软件类省赛真题(JAVA软件开发高职高专组部分习题)试题解答

     目录 1 猜年龄 2 组素数 3 第39级台阶 4 核桃的数量 5 打印十字图 6 买不到的数目   前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 猜年龄 标题: ...

  3. 2014年去哪儿网笔试题--有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来。

    有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来. 这两个文件内容如下: context.txt “并不是每个人都需要$(qunar)自己的粮食,$(f ...

  4. 算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答

    目录 1 马虎的算式 2 黄金连分数 3 有理数类 4 幸运数 5 连号区间数   前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 马虎的算式 标题: 马虎的算式 小明 ...

  5. 算法笔记_111:第五届蓝桥杯软件类省赛真题(Java本科A组)试题解答

     目录 1 猜年龄 2 李白打酒 3 神奇算式 4 写日志 5 锦标赛 6 六角填数 7 绳圈 8 兰顿蚂蚁 9 斐波那契 10 波动数列   前言:以下试题解答代码部分仅供参考,若有不当之处,还请路 ...

  6. 算法笔记_112:第五届蓝桥杯软件类省赛真题(Java本科B组)试题解答

     目录 1 武功秘籍 2 切面条 3 猜字母 4 大衍数列 5 圆周率 6 奇怪的分式 7 扑克序列 8 分糖果 9 地宫取宝 10 矩阵翻硬币   前言:以下试题解答代码部分仅供参考,若有不当之处, ...

  7. 算法笔记_199:第二届蓝桥杯软件类决赛真题(C语言本科)

    前言:以下代码部分仅供参考,C语言解答部分全部来自网友,Java语言部分部分参考自网友,对于答案的正确性不能完全保证. 试题1 数论中有著名的四方定理:所有自然数至多只要用四个数的平方和就可以表示. ...

  8. 算法笔记_207:第五届蓝桥杯软件类决赛部分真题(Java语言C组)

    目录 1 数字拆分 2 稍大的串   前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 数字拆分 正整数可以表示为若干正整数的累加和. 如,对于正整数n=6,可以分划为: 6 5+1 4+2 4+1+ ...

  9. 2014年百度之星程序设计大赛 资格赛第一题 (longlong)

    解题思路: 只要看(A-V)*K 这个公式的更新值是否大于等于A ,大于的话继续循环,否则报错 注意一点,数据会爆int WA代码: #include<stdio.h> int main( ...

随机推荐

  1. iOS开发——技术精华Swift篇&Swift 2.0和Objective-C2.0混编之第三方框架的使用

    swift 语言是苹果公司在2014年的WWDC大会上发布的全新的编程语言.Swift语言继承了C语言以及Objective-C的特性,且克服了C语言的兼容性问题.Swift语言采用安全编程模式,且引 ...

  2. Docker初步认识安装和简单实例

    前话 问题 开发网站需要搭建服务器环境,FQ官网下载软件包,搭建配置nginx,apache,数据库等.官网没有直接可用的运行版本,担心网络流传的非官方发布软件包不安全还得自行编译官方源码安装,忘记步 ...

  3. XP下,文件夹添加右键命令行

    原文:XP下,文件夹添加右键命令行 总共有3种方式: --------------------1---------------------------------------------------- ...

  4. Phalanx--hdu2859(dp 最大对称子图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2859 题意就是给你一个n*n的字符矩阵,从中选出一个最大的子矩阵(m*m)满足关于斜对角线(左下角到右 ...

  5. PowerDesigner-自定义生成WORD

    PowerDesigner-自定义生成WORD_旧梦重温 分类: web 2014-02-26 21:08 1563人阅读 评论(48) 收藏 举报   目录(?)[+] 1统一建立模型 2导出自定义 ...

  6. python2 和python3共存下问题

    一.使用python2 or python3 1. 使用python2 $ python xxx.py 2. 使用python3 $ python3 xxx.py 二.脚本调用 /usr/bin/en ...

  7. shell脚本学习笔记

    1.判断符号:中括号[ ] [ ]进行数据的判断,例如我想知道HOME这个变量是否为空,[ -z "$HOME" ],或者两个字符串是否相等,[ "$HOME" ...

  8. MySQL工具:管理员必备的10款MySQL工具

    MySQL是一个复杂的的系统,需要许多工具来修复,诊断和优化它.幸运的是,对于管理员,MySQL已经吸引了很多软件开发商推出高品质的开源工具来解决MySQL的系统的复杂性,性能和稳定性,其中大部分是免 ...

  9. nginx.conf 配置文件详解

    简单的实现nginx在前端做反向代理服务器的例子,处理js.png等静态文件,jsp等动态请求转发到其它服务器tomcat: user www www; worker_processes ; erro ...

  10. 【转载】正则表达式学习 & ASCII码表

    文章原地址: http://www.jb51.net/tools/zhengze.html <正则表达式30分钟入门教程> 其中有几个地方可以有笔记: \s 匹配任意的空白符 \b 匹配单 ...