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

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

网上大神有一种解法,就是变种实现标记方法,通过位标记来判断是否有重复字符,这种方法相对于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<

正确的实现方法,要用一个包含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;
}

你可能感兴趣的:(数据结构与算法)