应用于字符串的后缀数组的每一个元素都是字符型指针,用来指向一个字符串。采用编程珠玑中的例子。如字符串”banana”对应的字符数组为char *ap[6],且
ap[0] = "banana";
ap[1] =“anana”;
ap[2] =“nana”;
ap[3] =“ana”;
ap[4] =“na”;
ap[5] =“a”;
在字符串中查找某一个字符串或者字符串组的实际应用:在google搜索栏中输入的关键词匹配(当然这里面的算法有可能会高级得多)。编程珠玑中的一个典型例子:找出字符串"ask not what your country can do for you, but what can do foryour country"最长的重复字符串。用普通的算法需要O(n^2)时间复杂度,这对于字符串十分庞大时十分不利。根据作者记载,对于复杂度为O(n^2)的C语言算法来说,在主频为400MHz的奔腾计算机实现时,处理10^5(128kb左右)的数据需要1.7分钟左右,处理10^6(1M)左右的数据时需要2.8小时,处理10^7(约16M)数据时需要1.4周的时间。如果数据量达到M级,时间似乎显得有些漫长。在这种情况下就可以采用时间复杂度更加的算法。
如果给以上字符串定义一个后缀数组,最长的重复字符串只可能出现在至少前一个字符相同的后缀数组指向的字符串中,如此就需要对后缀字符数组排序,让后缀字符数组指向的字符串前面字符相同的后缀字符数组紧挨着,这样只需要ap[i]和ap[i+1]做比较以找出相同的字符串即可。这样就使O(n^2)变成了O(n)。
比如在1中的后缀字符数组ap,经过排序(可采用快速排序,实际应用的快速排序要编写代码避免快速排序的最坏情况O(n^2) )后就变成了:
ap[0] =“a”;
ap[1] =“ana”;
ap[2] =“anana”;
ap[3] =“banana”;
ap[4] =“na”;
ap[5] =“nana”;
这样就只需要比较a[i]和ap[i+1]就可以找出最长的重复字符串为”ana”。可以专门编写一个计算两后缀数组重复字符个数个函数comlen:
int comlen(char *p, char *q) { int i = 0; while *p && (*p++ == *q++) ++i; return i; }
有了这个函数后,再去查找字符串中重复的最大字符串就简单了。可以用以下代码实现:
int maxlen = 0; int len = 0; int maxi = 0; for(i = 0; i < n; ++i){ if( (len = comlen(a[i], a[i+1]) ) > maxlen) { maxlen = len; maxi = i; } }
这样就求得了重复的最长字符串在字符串中的位置的同时也求得了最大最大字符串的长度。可以将ap[maxi]至地址ap[maxi + maxlen]之间的字符串输出来。
分析,如果是求长度最大的重复字符串这个算法的程序完全适用,但如果是求长度最大的语句则这个算法的程序可能就不会再那么精确了。原因是有可能得出的字符串中的某个词语不是单词,如果实际中有这种需求时,可以利用“单词空格嵌套的字符串”等条件加以限制。
此次笔记记录完毕。