【Programming Pearls】查找一段文本或单词中的最长重复子串

           给定一个文本文件,查找最长的重复子串。

 如文本“Ask not what your country can do for you, but what you can do for your country”,最长的重复子串为“can do for you”和“your country”。单词banana的最长重复子串为“ana“。该问题可以看成是一个由颠倒字母组成的单词组合问题。假设该输入字符串保存在c[0…,n-1]数组中,一般比较常见的做法是用下面的伪代码来比较每个子串。

maxlen = -1

for i = [0, n)

for j = (i, n)

if (thislen = comlen(&c[i], &c[j])) > maxlen

maxlen = thislen

maxi = i

maxj = j

comlen()函数返回两个字符串中相同的最长的字符数目,从第一个字符开始计算。

int comlen(char *p, char *q)

i = 0

while *p && (*p++ == *q++)

i++

return i

 

由于上面的算法要比较所有可能的子串对,所以时间复杂度比较高,为o(n^2)。我们可以采用“后缀数组“来降低它的时间复杂度。

假设处理的文本的字符总数最多为MAXN,保存在数组c中。

#define MAXN 5000000

char c[MAXN], *a[MAXN];

其中数组a为后缀数组。

 

初始化代码如下:

while (ch = getchar()) != EOF

a[n] = &c[n]

c[n++] = ch

c[n] = 0

 

其中a[0]指向整个字符串,a[1]指向从第二个字符开始往后的所有字符,依次类推。如下:

a[0]: banana

a[1]: anana

a[2]: nana

a[3]: ana

a[4]: na

a[5]: a

 

如果一个长字符串在C中出现两次,它们的后缀不相同。然后按照字母顺序对数组a的字符串进行排序,然后比较相邻的字符串,找出最长的重复子串为ana。

a[0]: a

a[1]: ana

a[2]: anana

a[3]: banana

a[4]: na

a[5]: nana

 

这里采用qsort对“后缀数组“进行排序。

qsort(a, n, sizeof(char *), pstrcmp);

 

用下面的代码比较相邻字符串的最大长度:

for i = [0, n)

if comlen(a[i], a[i+1]) > maxlen

maxlen = comlen(a[i], a[i+1])

maxi = i

printf("%.*s\n", maxlen, a[maxi])

 

 

完整的代码如下:

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

int pstrcmp(char **p, char **q)

{ return strcmp(*p, *q); }

int comlen(char *p, char *q)

{ int i = 0;

while (*p && (*p++ == *q++))

i++;

return i;

}

#define M 1

#define MAXN 5000000

char c[MAXN], *a[MAXN];

int main()

{ int i, ch, n = 0, maxi, maxlen = -1;

while ((ch = getchar()) != EOF) {

a[n] = &c[n];

c[n++] = ch;

}

c[n] = 0;

qsort(a, n, sizeof(char *), pstrcmp);

for (i = 0; i < n-M; i++)

if (comlen(a[i], a[i+M]) > maxlen) {

maxlen = comlen(a[i], a[i+M]);

maxi = i;

}

printf("%.*s\n", maxlen, a[maxi]);

return 0;

}

 


### 回答1: 《编程珠玑》是一本经典的计算机编程书籍,由Jon Bentley所著。书作者以宝石的形式,以自己在编程领域的经验和思考作为原料,展现了许多精彩的编程技巧和解决问题的思路。 这本书被誉为计算机界的经典之作,其价值不仅在于作者分享的个人经验,更在于其蕴含的许多智慧和洞见。书的每个章节都涵盖了一个独立的编程话题,包括算法优化、代码调试、程序设计等,并通过大量的实例和案例讲解了相应的技巧和方法。这些实例涵盖了几乎所有计算机领域,包括排序、查找、字符串处理等,从而帮助读者理解和掌握这些技巧。 与其他编程书籍不同,《编程珠玑》强调的是实用性和深度思考。书的每个问题都是作者亲自经历过的,每个解决方案都是经过深思熟虑的。通过阅读这本书,读者可以学习到如何通过合理的数据结构和算法设计,将问题简化并高效解决。同时,作者还教会了读者如何思考和分析问题,如何避免一些常见的陷阱和错误。 《编程珠玑》不仅适合初级的程序员,也适合有一定编程经验的开发者阅读。无论是学习编程的初学者,还是已经有多年开发经验的工程师,都可以通过阅读这本书,提升自己的编程能力和思维方式。读者可以在书找到灵感和启示,解决实际的编程难题,并学到一些通用的编程技巧和原则。 总之,《编程珠玑》是一本极具价值的编程书籍,其内容丰富实用,思想深入,对于提升编程能力和思维方式都具有重要意义。无论是想成为一名优秀的程序员,还是找到解决实际问题的思路,这本书都值得一读。 ### 回答2: 《编程珠玑》是由Jon Bentley于1986年出版的一本经典计算机科学书籍。书主要讨论了各种编程问题和解决方案,旨在帮助读者提高编程技巧和思维能力。 这本书是由编程问题组成的,每个问题都来自实际编程的实际情况。每个问题都是用C语言描述并解决的。在解决问题的过程,书提出了一些有趣的技巧和方法,例如位操作、动态规划、递归和分治等。这些技巧和方法不仅可以帮助我们解决具体的问题,还可以帮助我们提高编程效率和代码质量。 《编程珠玑》的作者Jon Bentley是一位计算机科学家,他在书分享了他多年来在编程领域的经验和见解。通过这本书,读者可以学到很多关于编程的技巧和思维方式,有助于提高解决实际编程问题的能力。 总的来说,《编程珠玑》是一本非常有价值的编程书籍,无论是初学者还是有经验的程序员都可以从受益。它可以帮助我们了解并掌握解决实际编程问题的方法和技巧,提高我们的编程能力和思维能力。如果你对编程有兴趣,并且想提高自己的编程技术,我强烈推荐你阅读这本书。 ### 回答3: 《编程珠玑》是一本由Jon Bentley编写的计算机科学经典著作,被誉为程序员必读之书。该书探讨了一系列关于编程和算法的知识和技巧,以及一些经典的编程问题和解决方法。 《编程珠玑》的主要目的是通过具体的编程案例和讨论,帮助读者提高编程技巧和解决问题的能力。书提供了众多的编程小技巧和优化思路,让程序员能够对复杂问题进行有针对性的分析和解决。这些技巧涵盖了各个方面,包括数据结构、算法设计、性能优化等。 该书的编程珠玑主要包括程序设计的三个重要原则:正确性、性能和可读性。作者通过讲述自己的实践经验,以及一些经典的编程问题和解决方法,来阐述这些原则。读者可以通过学习和理解这些原则,提高自己的程序设计能力,并编写出更加优秀的代码。 除了传授编程技巧和知识外,该书还强调了问题解决的思维方式。作者通过讲述一些实际问题的解决过程,鼓励读者灵活运用各种方法和工具,来解决复杂的编程难题。这种思维方式对于程序员来说非常重要,可以培养解决问题的能力,提高工作效率。 总的来说,《编程珠玑》是一本经典的计算机科学读物,通过具体的案例和讨论,帮助读者提高编程技巧和解决问题的能力。无论是想提升自己的程序设计能力,还是希望更好地解决编程难题,这本书都是值得一读的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值