实现一个算法,确定一个字符串的所有字符是否全部都不同。

程序员面试金典:实现一个算法,确定一个字符串的所有字符是否全部都不同。

网上大神有一种解法,就是变种实现标记方法,通过位标记来判断是否有重复字符,这种方法相对于bool标记数组可以节省空间。先看代码:

bool IsStrHasDiffCharacters(string &str)
{
	if (str.length()>256)
	{
		return false;
	}

	int nChecker = 0;
	for (int i=0;i<str.length();i++)
	{
		int val = str.at(i); // 第i个字符在ASCII码中的位置
		if ((nChecker&(1<<val))>0)  // 将1左移val位,再与nChecker做&运算
		{
			return false;  // 如果此位已经有1,说明已经出现过该字符,结果就是>0,返回false
		}

		nChecker |= (1 << val); // 如果&结果为0,说明没有出现过该字符,将此位置1
	}

	return true;
}

通过上述代码可以发现,只用一个int nChecher作为位标记。刚开始看得一头雾水,32位怎么可能实现ASCII码最多256个字符的标记呢?不是应该要256位才行么?百思不其解。仔细想了一下,这种方法还是有问题,移位操作1<<val这里,整型当val大于32位时,会作截断处理,即1<<32 相当于1<<0 ,当存在两个字符ASCII位置相差32时,这两个不同的字符1<<val是相等的,比如str=“1Q”,这时会判断已经存在,返回false。通过实际代码运行,上述代码是有错误的,所以平时在网上看到代码,一定要实践测试,照抄照搬是不可行的。

正确的实现方法,要用一个包含256个bits的位向量,代码如下所示:

bool INTERVIEW_ALG::IsStrHasDiffCharactersNew(string &str)
{
	if (str.length() > 256)
	{
		return false;
	}

	int *pBook = new int[256 / sizeof(int)];
	memset(pBook, 0, 256);

	for (int i = 0; i < str.length(); i++)
	{
		int nPos = str.at(i); // 第i个字符在ASCII码中的位置


		if ((pBook[nPos / 32] & 1 << (nPos % 32)) > 0)
		{
			return false;  // 如果此位已经有1,说明已经出现过该字符,结果就是>0,返回false
		}

		pBook[nPos /32] |= 1<<(nPos %32); // 如果&结果为0,说明没有出现过该字符,将此位置1
	}
	
	delete[]pBook;
	return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值