[算法 笔记]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个时,将退出。
// 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修正的更多相关文章
- 算法笔记_108:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科A组)试题解答
目录 1 世纪末的星期 2 振兴中华 3 梅森素数 4 颠倒的价牌 5 三部排序 6 逆波兰表达式 7 错误票据 8 带分数 9 剪格子 10 大臣的旅费 前言:以下试题解答代码部分仅供参考,若有不 ...
- 算法笔记_110:第四届蓝桥杯软件类省赛真题(JAVA软件开发高职高专组部分习题)试题解答
目录 1 猜年龄 2 组素数 3 第39级台阶 4 核桃的数量 5 打印十字图 6 买不到的数目 前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 猜年龄 标题: ...
- 2014年去哪儿网笔试题--有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来。
有两个文件context.txt和words.conf,请尝试将他们合并成为一段文字,并打印出来. 这两个文件内容如下: context.txt “并不是每个人都需要$(qunar)自己的粮食,$(f ...
- 算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答
目录 1 马虎的算式 2 黄金连分数 3 有理数类 4 幸运数 5 连号区间数 前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 马虎的算式 标题: 马虎的算式 小明 ...
- 算法笔记_111:第五届蓝桥杯软件类省赛真题(Java本科A组)试题解答
目录 1 猜年龄 2 李白打酒 3 神奇算式 4 写日志 5 锦标赛 6 六角填数 7 绳圈 8 兰顿蚂蚁 9 斐波那契 10 波动数列 前言:以下试题解答代码部分仅供参考,若有不当之处,还请路 ...
- 算法笔记_112:第五届蓝桥杯软件类省赛真题(Java本科B组)试题解答
目录 1 武功秘籍 2 切面条 3 猜字母 4 大衍数列 5 圆周率 6 奇怪的分式 7 扑克序列 8 分糖果 9 地宫取宝 10 矩阵翻硬币 前言:以下试题解答代码部分仅供参考,若有不当之处, ...
- 算法笔记_199:第二届蓝桥杯软件类决赛真题(C语言本科)
前言:以下代码部分仅供参考,C语言解答部分全部来自网友,Java语言部分部分参考自网友,对于答案的正确性不能完全保证. 试题1 数论中有著名的四方定理:所有自然数至多只要用四个数的平方和就可以表示. ...
- 算法笔记_207:第五届蓝桥杯软件类决赛部分真题(Java语言C组)
目录 1 数字拆分 2 稍大的串 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 数字拆分 正整数可以表示为若干正整数的累加和. 如,对于正整数n=6,可以分划为: 6 5+1 4+2 4+1+ ...
- 2014年百度之星程序设计大赛 资格赛第一题 (longlong)
解题思路: 只要看(A-V)*K 这个公式的更新值是否大于等于A ,大于的话继续循环,否则报错 注意一点,数据会爆int WA代码: #include<stdio.h> int main( ...
随机推荐
- J-link V8固件升级记
http://blog.sina.com.cn/s/blog_5bdee3020101khfy.html 好久没为电子工程事业尽份力了!今天也稍微努把力!写写我是如何升级J-link的固件的吧! J- ...
- x11vnc
http://cisight.com/how-to-setup-vnc-server-remote-desktop-in-ubuntu-11-10-oneiric/ Install VNC serve ...
- 12个QT基本对话框,以及淡入原理(用定时器把窗口逐渐变成透明)
一.基本对话框 1,核心库: 界面程序 QApplication 非程序界面QCoreAppliction 2,消息循环必须执行QApplication.exec(); 3,消息绑定机制: 信号-槽 ...
- AngularJs+bootstrap搭载前台框架——准备工作
1.关于什么是AngularJs以及什么是bootstrap我就不多说了,简单说下,AngularJs是一个比较强大前台MVC框架,bootstrap是Twitter推出的一个用于前端开发的开源工具包 ...
- 关于请求添加HttpRequestHeader
WebClient w = new WebClient(); w.Headers.Add(HttpRequestHeader.Accept, "application/json") ...
- C# 值类型和引用类型的区别
C# 值类型和引用类型的区别 1. 值类型的数据存储在内存的栈中:引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址. 2. 值类型存取速度快,引用类型存取速度慢. 3. 值类型表示实 ...
- hdu - 1242 Rescue && hdu - 2425 Hiking Trip (优先队列+bfs)
http://acm.hdu.edu.cn/showproblem.php?pid=1242 感觉题目没有表述清楚,angel的朋友应该不一定只有一个,那么正解就是a去搜索r,再用普通的bfs就能过了 ...
- 51 nod 1006 最长公共子序列Lcs
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006 参考博客 :http://blog.csdn.net/yysdsy ...
- pyhton与json,Xml
对简单数据类型的encoding 和 decoding: 使用简单的json.dumps方法对简单数据类型进行编码,例如: 1 2 3 4 5 6 import json obj = [[1,2, ...
- Android实现自定义字体
介绍 最近在看开源项目的时候,发现里面涉及到了自定义字体,虽然自己目前还用不到,但是动手demo笔记记录一下还是有必要的,没准哪天需要到这个功能. 原理 1.其实实现起来非常简单,主要是用到了Type ...