您的位置:首页 > 职场人生

一道面试题引发的思考

2012-10-11 19:43 543 查看
1.昨天(10月10日)腾讯一面,一道简单的面试题,本以为写得还不错,结果今天回来仔细思考并coding,发现此程序中漏洞多多。

2.题意:删除一个字符串中重复出现的字符,只留下第一次出现的字符。如:输入abaacdba,输出abcd。

3.思路:定义一个数组来存放每个字符出现的次数,如果发现字符已经出现,则删除该字符。

4.代码:

(1)当时写的版本:

char* DeleteFun(char* str)
{
int times[WordNumber];
for (int i = 0; i < WordNumber; i++)
{
times[i] = 0;
}

char* p = str;
int index;
while (*p != '\0')
{
index = *p - 'a';
if (times[index] == 0)
{
times[index]++;
}
p++;
}

p = str;
char* ret = str;

while (*p != '\0')
{
index = *p - 'a';
if (times[index] != 0)
{
times[index] = 0;
*ret = *p;
ret++;
}
p++;
}
ret++;
*ret = '\0';

return str;
}
(2)当时检查了一遍,发现没有加 *ret = '\0'这一句,加上之后自以为还比较满意。

5.回来发现的问题

(1)最后ret++是多余的,有错的,加了这一句会多一个字符;

(2)时间花费了2*N,开销有点大;

(3)这里只考虑了26个小写字母,而没有考虑大写字母和特殊字符。

6.刚刚仔细想想,并且在与kk同学的讨论中,把程序改进了一下,如下:

char* DeleteFun1(char* str)
{
int times[256];
//memset(times, 0, 256 * sizeof(int));
memset(times, 0, sizeof(times));

char *p = str;
char *q = str;
while (*p != '\0')
{
if (times[*p] != 0)
{
p++;
}
else
{
times[*p] = 1;
*q = *p;
p++;
q++;
}
}
*q = '\0';
return str;
}
几点思考:

(1)出现次数数组大小为256,可以容纳所有的大小写字母和特殊字符;

(2)初始化使用memset,比用for循环效率高,而且写得更简单;

(3)只要用一个循环即可,即扫描的时候即判断这个字符是否是出现了,如果没有出现则留下这个字符,如果已经出现了则直接pass掉;

(4)不用加index这个变量,也不用做操作*p - 'a',可以直接用*p来作下标(因为开了256大小的数组);

(5)sizeof(times)的大小和256 * sizeof(int)的大小是一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: