字符串处理面试题_字符串包含问题

为了准备面试中出现的字符串问题,我决定做一个系列,以我自己的标准,将自己认为比较优秀的字符串面试题整理一些。希望这样做能够形成解决字符串问题的一般思路,能够比较高效地解决字符串问题。

故特别声明:所有问题的解决思路都是网上大牛们提供的,感谢他们的分享。我做的事情是理解这些思路,用自己的话转述一遍,而不是简单地复制粘贴。我也会注明资料的来源,如果作者觉得有侵权行为,请联系我。

这个问题是看了http://blog.csdn.net/v_JULY_v/archive/2011/04/23/6347454.aspx, https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.02.md(感谢@v_JULY_v)。

问题描述:有两个任意字符串sting A, sting B, 实现如下函数 int Contain( string &a, sting &b),如果a 里面包含b所有出现的字符,函数返回TRUE,其它情况返回FALSE。相当于集合上的包含问题。

@v_JULY_v提供了大致四种思路:轮训,排序轮训,素数相乘,及利用hash查找的思想(包括)。

学习了解了这些思路之后,我比较喜欢的是轮训这种方法,这种方法很笨,但却是最直观,最容易想到的方法。但除此之外,应该掌握一种复杂度比较小的一种方法。采用hash查找的方法,可以将时间复杂度降到O(m+n),空间复杂度降到O(1)。

采用hash查找思想的思路这样的:

step1:先分配一个整数数组hash[max],数组大小为字符集个数(ASCII码为256),并初始化为0。

step2:然后开始遍历Stirng A,然后将整形数组中位置为这些字符的ASCII值的元素增1;比如出现‘A’,的ascii为65,那么hash[65]++;

step3:遍历StingB,如果数组里面那些位置为SringB字符集里的ASCII值的元素都不为0,则字符串A包含字符串B,

代码实现:

int contain(const char *stra, const char *strb)
{
	int hash[256] = {0};
	const char *p = stra;
	while( *p != '\0')
	{
			hash[*p++]++;
	}
   	p = strb;
   	while( *p != '\0')
   	{
	   if(hash[*p] == 0)
		   return -1;// failed!
	   p++;
   	}
   	return 0;// succeed!
}


这个思路可以改进为:用比特位来表示StringA里字符的出现。具体代码参见@v_JULY_v相应的代码。不过他把问题进行了简化,字符集仅限于大写字母,故只需要一个整数,就可以表示所有的字符出现标志,其实只要26个。但是字符集扩大的话,比如128,256,这就无法用一个int或者long来表示了。可以用结构体来实现。

typedef struct 
{
	long long a;
	long long b;
	long long c;
	long long d;
} hash;
int move(hash *h,char a)//
{
	long long moveval = a % 64;
	if( a >=0 && a < 64)
		h->a |= 1 << moveval;
	else if(a > 63 && a < 128)
		h->b |= 1 << moveval;
	else if( a > 127 && a < 192)
		h->c |= 1 << moveval;
	else //if(a > 191 && a < 256)
		h->d |= 1 << moveval;
	return 0;

}

int hashflag(hash *h, char c)
{
	int moveval = c % 64;
	if(c >=0 && c < 64)
		return h->a & (1 << moveval);
	else if(c > 63 && c < 128)
		return h->b & ( 1 << moveval);
	else if(c > 127 && c < 192)
		return h->c & ( 1 << moveval);
	else
		return h->d &  ( 1 << moveval);
}


int strContain(const char *stra, const char *strb)
{
	hash h;
	h.a = 0;
	h.b = 0;
	h.c = 0;
	h.d = 0;
	const char *p = stra;
	while(*p != '\0')
		move(&h, *p++);
	p =strb;
	while(*p != '\0')
	{		
		if(hashflag(&h, *p++) == 0)
			return -1;
	}
	return 0;

}


你可能感兴趣的:(字符串处理面试题_字符串包含问题)