一道面试题引发的思考

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)的大小是一样的。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值