最长重复数组
来源:互联网 发布:淘宝网苹果7都下架了 编辑:程序博客网 时间:2024/06/01 11:05
最长重复数组,具体可以参考编程珠玑15章
给定一个文本文件作为输入,插在其中最长的重复子字符串。例如,“Ask not what your country can do for you, but what you can do for your country”中最长的重复字符串是“can do for you”,第二长的是“your country”。
方法一:双重for循环依次比较每个字符串,找到最长重复子字符串
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- //找到两个字符串公共部分的长度
- int comlen(char *p, char *q)
- {
- int i = 0;
- while (*p && (*p++ == *q++))
- {
- i++;
- }
- return i;
- }
- int main()
- {
- int i, j;
- int maxi, maxj;
- int currentlen, maxlen = -1;
- char *str = "ask not what your country can do for you, but what you can do for your country";
- int length = strlen(str);
- for(i = 0; i < length; i++)
- {
- for(j = i + 1; j < length; j++)
- {
- currentlen = comlen(str + i, str + j);
- if(currentlen > maxlen)
- {
- maxlen = currentlen;
- maxi = i;//i标记了最长公共子串开始的位置
- maxj = j;
- }
- }
- }
- for(i = 0; i < maxlen; i++)
- {
- printf("%c", str[maxi + i]);
- }
- printf("n");
- return 0;
- }
方法二:采用后缀数组来处理该问题
我们的程序最多处理MAXN个字符,这些字符存储在数组c中。
#define MAXN 50000
char c[MAXN], *a[MAXN];
我们使用一个称为“后缀数组”的数据结构,这个结构是一个字符指针数组,记为a。读取输入时,我们对a进行初始化,使得每个元素指向输入字符串中的相应字符:
while(ch = getchar() != EOF)
{
a[n] = &c[n];
c[n] = ch;
}
c[n] = 0;
元素a[0]指向整个字符串,下一个元素指向从第二个字符开始的数组后缀,等等。对于输入字符串“banana”,该数组能够表示如下后缀:
char *a="banana"
a[0]=banana
a[1]=anana
a[2]=nana
a[3]=ana
a[4]=na
a[5]=a
如果某个长字符串在数组c中出现了两次,那么它将出现在两个不同的后缀中,因此我们队数组进行排序以寻找相同的后缀。“banana”数组排序为:
a[0]=a
a[1]=ana
a[2]=anana
a[3]=banana
a[4]=na
a[5]=nana
然后就可以扫描数组,通过比较相邻元素来找出最长的重复字符串。
该方法由于排序的存在,时间复杂度为O(nlogn)。
#include <stdlib.h>#include <string.h>#include <stdio.h>//只能比较字符串,两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇''为止。int pstrcmp(const void *p, const void *q){return strcmp(*(char **)p, *(char **)q);}int comlen(char *p, char *q)//返回两个参数共同部分的长度 { int i = 0;while (*p && (*p++ == *q++))i++;return i;}#define M 1#define MAXN 5000000char 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;}
- 最长重复数组
- 最长重复子串(后缀数组)
- 后缀数组求最长重复子串
- 后缀数组求最长重复子串
- 后缀数组:最长重复子串 (marked)
- 后缀数组求最长重复子串
- 后缀数组求最长重复子串
- 后缀数组之最长重复子串
- 后缀数组应用(最长重复子字符串)
- 最长重复子串—后缀数组
- 后缀数组求最长重复子串
- 后缀数组求最长重复子串
- 后缀数组求最长重复子串
- 最长重复子串(后缀数组思想)
- 后缀数组求最长重复子串
- 字符串相关处理kmp,前缀数,后缀树,后缀数组,最长回文串,最长重复字串,最长非重复字串
- 字符串相关处理kmp,前缀数,后缀树,后缀数组,最长回文串,最长重复字串,最长非重复字串
- 字符串相关处理kmp,前缀数,后缀树,后缀数组,最长回文串,最长重复字串,最长非重复字串
- PE感染型病毒代码 大部分有注释
- Oracle用spool导出数据
- couldn't set locale: correctly报错的解决
- 快速上手RaphaelJS--RaphaelJS_Starter翻译(三)
- 扩展 ZF2 Redis Zend Framework 2 Redis Extend - key正则
- 最长重复数组
- Open XML SDK 现已经由 GitCafe 登陆中国开源社区
- 日语学习之沪江N4基础 20141201
- ZF2表单操作
- mysql存储过程
- iOS学习--UIScrollView 原理详解
- duplicateMovieClip
- 西门子PLC学习笔记十-(计数器)
- sip参考大全