`
把酒泯恩仇
  • 浏览: 26440 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

字符串处理新思维啊【不得不看】

阅读更多

 

请查看原文:

http://www.ibaiyang.org/2012/03/25/repeat-substring/

最近在看《编程珠玑》,很多人说,应该看看这本神书,于是跟风,我也买了一本,不过才拿到这本书的时候,觉得也是一般,前面几章的例题很是一般,而且感觉作者分析的东西自己不是很实用,比如二分搜索就讲了2,3章,虽然作者对二份搜索的理解与实现,吹毛求疵,但是整体上来说,觉得没有意思,没有给人一张豁然开朗的感觉,在看到第二章时,讲到了变位词的算法,才令人痴迷,于是我疯狂的继续看下去,今天看到了重复字符串的实现方式,我高兴的立刻想发篇博文,来证实它多么的奇妙。

求一个字符串的最长重复字符串,就是在一个长字符串中,找出有重复的字符串,且其长度最长,我感觉这个题的引申意义也很大,特别在如今搜索引擎的时代。例如banana的最长字符串是ana,tian xian的最长字符串是ian。好了,看看是怎么实现的吧。

int cmp_str(char* p, char* q)
{
	int size = 0;
	while(p && q && *p == *q){
		size++;
		p++;
		q++;
	}
	return size;
}

int maxlen = -1;
int current_size = -1;
for(int i = 0; i < n; i++){
	for(int j = i + 1; j < n; j++){
                if( (current_size = cmp_str(&input_string[i], &input_string[j]) ) > maxlen ){
			maxlen    = current_size;
			low_index = i;
			high_index = j;
		}
	}
}

其中最大的字符串长度存在原字符串中的i到j的位置,当然这是任何人都能想到的2B算法,我也包括在列,哎,继续努力吧。

那么,作者怎么看待这个问题的呢,其中用到了“后缀数组”,很早之前,就听某位ACM队员将过后缀数组,但是不知道他说的是什么,也没有追问,今天碰巧又遇到了它,冤家路窄啊。

什么是后缀数组呢,其实很简单,我觉得这个属于程序预处理部分,一个简单的数据结构。

这个结构是一个字符指针数组,假设记为word。读取字符时,我们对word进行初始化,使得每个元素指向输入字符串中的相应字符

int i = 0;
	char ch;
	while( (ch = cin.get()) != '\n' ){
		input_string[i] = ch;
		word[i++]       = &input_string[i];
		max_word++;
	}

	input_string[i] = '\0';
	word[i]         = NULL;

那么举个例子吧,如我们输入的字符串是baiyang,则

word[0] = "baiyang";
word[1] = "aiyang";
word[2] = "iyang";
word[3] = "yang";
word[4] = "ang";
word[5] = "ng";
word[6] = "g";

这些就成为“后缀数组”,如果你能理解二叉树,我相信这个也能理解吧。

如果某个长字符串在数组中出现二次,那么它将出现在二个不同的后缀中,因此我们队数组排序以寻找相同的后缀。

如对banana的后缀数组排序为

word[0] = "a";
word[1] = "ana";
word[2] = "anana";
word[3] = "banana";
word[4] = "na";
word[5] = "nana";

于是看到ana为最长,分别存在1,2二个后缀数组中。
当我们对后缀数组排好序之后,我们就可以遍历数组了

	int i = 0;
	int index   = -1;
	int max_len = -1;

	int current_size = 0;
	for(i = 0; i < max_word - 1; i++) { 		if( (current_size = cmp_str(word[i], word[i+1])) > max_len ) {
			max_len = current_size;
			index   = i;
		}
	}

这样,最长的子字符串的长度就是max_len了,而起点就是index位置。故解决,算法复杂度由之前的n平方,降到了nlog(n)了。不过我觉得其中的后缀数组结构值得我们思考一下。

转载:http://www.ibaiyang.org/2012/03/25/repeat-substring/  支持正版

 

-----------------打造高质量的文章 更多关注 把酒泯恩仇---------------

为了打造高质量的文章,请  推荐  一下吧。。。。谢谢了,请关注我后续的文章,会更精彩哦

请关注sina微博:http://weibo.com/baiyang26

把酒泯恩仇官方博客:http://www.ibaiyang.org 【推荐用google reader订阅】

把酒泯恩仇官方豆瓣:http://www.douban.com/people/baiyang26/

如果您想转载本博客,请注明出处

如果您对本文有意见或者建议,欢迎留言

 

3
2
分享到:
评论
3 楼 zui4yi1 2012-12-11  
&&这些拷贝的东东,可不可以改一下,差一点觉得自己忘记C了。。。
2 楼 把酒泯恩仇 2012-12-11  
wupuyuan 写道
书里有很多算法的确是属于搜索的技巧,但是内存开销也大,不适合大数据使用。不过这些算法的确很棒!

的确。。。。看来你也是算法高手吗
1 楼 wupuyuan 2012-12-11  
书里有很多算法的确是属于搜索的技巧,但是内存开销也大,不适合大数据使用。不过这些算法的确很棒!

相关推荐

Global site tag (gtag.js) - Google Analytics