后缀数组法求最长重复子串

/************************************************************************/
/* 功能:求字符串的最长重复子串
采用后缀数组思想。对于“banana”这个串的后缀数组为:
char* suff[30];//字符串指针数组
suff[0]:banana
suff[1]:anana
suff[2]:nana
suff[3]:ana
suff[4]:na
suff[5]:a
排序之后,suff里的元素,分别指向
suff[0]:a
suff[1]:ana
suff[2]:anana
suff[3]:banana
suff[4]:na
suff[5]:nana
*/
/************************************************************************/
#include<iostream>
#include<cstring>
using namespace std;
char* suff[30];
int maxlen;/*记录最长重复子串长度 */
char * pMax = NULL;  /* 记录最长重复子串的起始位置 */
void outputLRS();  /* 输出LRS */ 

/************************************************************************/
/*
p:字符串
q:字符串
功能:比较两个字符串的大小
*/
/************************************************************************/
int pstrcmp(const void* p, const void* q)
{
	return strcmp(*(const char**)p,*(const char**)q);
}

/************************************************************************/
/*
p:字符串
q:字符串
功能:计算两个字符串包含第一位字符在内的最长公共子串长度。如abc与adbc,长度为1即a,而不是2即bc。
*/
/************************************************************************/
int comlen(char * p, char * q) 
{    
	int len = 0;   
	while(*p && *q && *p++ == *q++) 
	{        
		++len; 
	}    
	return len; 
}   


/************************************************************************/
/* 
arr:字符指针,原始字符数组或者字符串
size:字符数组长度
*/
/************************************************************************/
void LRS_suffix(char* arr, int size)
{
	int suff_index =  maxlen  = 0;
	for (int i = 0; i < size; ++i)/*初始化后缀数组*/
		suff[i] = &arr[i];
	qsort(suff, size, sizeof(char*), pstrcmp);/* 排序后缀 */
	for (int i = 0; i < size-1;++i)/* 寻找最长重复子串 */
	{
		int len = comlen(suff[i], suff[i+1]);
		if (len > maxlen)
		{

			maxlen = len;
			pMax = suff[i];
		}
	}
	outputLRS();

}


/* 输出LRS 
 * 在后缀数组方法中,maxindex=0
 * 因为传进来的就是后缀数组suff[],从0打印maxlen个字符
*/
void outputLRS()
{
	if(maxlen == 0)
	{
		printf("NULL LRS\n");
		return;
	}
	printf("The len of LRS is %d\n",maxlen);

	char *p = pMax;
	for (int i=0;i<maxlen; ++i)
	{
		printf("%c", *(p+i));
	}
	printf("\n");
}

void main()
{
	char X[] = "bsdanande";

	/* 后缀数组方法 */
	LRS_suffix(X,strlen(X));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值