后缀数组详解

这是一部分,以后还会更新的

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 10000
using namespace std;

char s[maxn],s1[maxn];
int sa[maxn];/***sa[第几大]=第几位开始的后缀***/
int Rank[maxn];/***rank[第几位开始的后缀]=第几大***/
int t[maxn],t2[maxn],c[maxn],n;

void build_sa(int m)
{
	int i,*x=t,*y=t2;
	//基数排序
	for(i=0;i<m;++i)c[i]=0;
	for(i=0;i<n;++i)c[x[i]=s[i]]++;
	for(i=1;i<m;++i)c[i]+=c[i-1];/**计算出每种字母排第几**/
	for(i=n-1;i>=0;--i)sa[--c[x[i]]]=i;
	for(int k=1;k<=n;k<<=1)
	{
		int p=0;
		/**直接利用sa数组排序第二关键字**/
		for(i=n-k;i<n;++i)y[p++]=i;
		for(i=0;i<n;++i)
			if(sa[i]>=k)y[p++]=sa[i]-k;
		/**基数排序第一关键字**/
		for(i=0;i<m;++i)c[i]=0;
		for(i=0;i<n;++i)c[x[y[i]]]++;
		for(i=0;i<m;++i)c[i]+=c[i-1];
		for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
		/**根据sa和y数组计算新的x数组**/
		swap(x,y);
		p=1;x[sa[0]]=0;
		for(i=1;i<n;++i)
			x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
		if(p>=n)break;/**以后即使继续倍增,sa也不会改变,退出**/
		m=p;/**下次基数排序的最大值**/
	}
}

int m;
int cmp_suffix(char *pattern,int p)
{
	return strncmp(pattern,s+sa[p],m);
	/***************************
	用 法: int strncmp(char *str1, char *str2, int maxlen);
说明:此函数功能即比较字符串str1和str2的前maxlen个字符。
如果前maxlen字节完全相等,返回值就=0;
在前maxlen字节比较过程中,如果出现str1[n]与str2[n]不等,
则返回(str1[n]-str2[n])。
	****************************/
}

int find(char *p)
{
	m=strlen(p);
	if(cmp_suffix(p,0)<0)return -1;/**下界为第0个后缀**/
	if(cmp_suffix(p,n-1)>0)return -1;/**上界为第n-1个后缀**/
	int l=0,r=n-1;
	while(r>=l)/**二分判断是否有该后缀与P的公共前缀=p的长度**/
	{
		int m=l+(r-l)/2;
		int res=cmp_suffix(p,m);
		if(!res)return m;
		if(res<0)r=m-1;else l=m+1;
	}
	return -1;
}


int main()
{
    scanf("%s",s);
    n=strlen(s);
    build_sa(300);/**char的最大字符值**/
    scanf("%s",s1);
    cout<<find(s1);/**从s中查找s1**/
	return 0;
}

 

 

 

下面这个是基础版,常数会大些,复杂度不变

 1 #include <iostream>
 2 #include <string>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdio>
 6 #define maxlen 1000
 7 #define maxn 10000
 8 
 9 using namespace std;
10 
11 char s[maxlen],s1[maxlen];
12 int sa[maxn],tsa[maxn],Rank[maxn],trank[maxn],sum[maxn];
13 int n,m;
14 
15 void sorting(int j)
16 {
17     memset(sum,0,sizeof(sum));
18     for(int i=1;i<=n;i++)sum[Rank[i+j]]++;
19     for(int i=1;i<=maxlen;i++)sum[i]+=sum[i-1];
20     for(int i=n;i!=0;i--)tsa[sum[Rank[i+j]]--]=i;
21 
22     memset(sum,0,sizeof(sum));
23     for(int i=1;i<=n;++i)sum[Rank[i]]++;
24     for(int i=1;i<=maxlen;++i)sum[i]+=sum[i-1];
25     for(int i=n;i!=0;i--)sa[sum[Rank[tsa[i]]]--]=tsa[i];
26 }
27 
28 void build_sa()
29 {
30     int p;
31     for(int i=0;i!=n;++i)trank[i+1]=s[i];
32     for(int i=1;i<=n;++i)sum[trank[i]]++;
33     for(int i=1;i<=maxlen;++i)sum[i]+=sum[i-1];
34     for(int i=n;i!=0;i--)sa[sum[trank[i]]--]=i;
35     Rank[sa[1]]=1;
36     for(int i=2,p=1;i<=n;++i)
37     {
38         if(trank[sa[i]]!=trank[sa[i-1]])p++;
39         Rank[sa[i]]=p;
40     }
41     for(int j=1;j<=n;j*=2)
42     {
43         sorting(j);
44         trank[sa[1]]=1;p=1;
45         for(int i=2;i<=n;++i)
46         {
47             if((Rank[sa[i]]!=Rank[sa[i-1]]) || (Rank[sa[i]+j]!=Rank[sa[i-1]+j]))p++;
48             trank[sa[i]]=p;
49         }
50         for(int i=1;i<=n;++i)Rank[i]=trank[i];
51     }
52 }
53 
54 void init()
55 {
56     memset(sum,0,sizeof(sum));
57     memset(Rank,0,sizeof(Rank));
58     memset(trank,0,sizeof(trank));
59     memset(sa,0,sizeof(sa));
60     memset(tsa,0,sizeof(tsa));
61 }
62 
63 int cmp_suffix(char *pattern,int p){return strncmp(pattern,s+sa[p]-1,m);}
64 
65 int finds(char *p)
66 {
67     m=strlen(p);
68     if(cmp_suffix(p,1)<0)return -1;
69     if(cmp_suffix(p,n)>0)return -1;
70     int l=1,r=n;
71     while(r>=l)
72     {
73         int m=l+(r-l)/2;
74         int res=cmp_suffix(p,m);
75         if(!res)return m;
76         if(res<0)r=m-1;else l=m+1;
77     }
78     return -1;
79 }
80 
81 int main()
82 {
83     init();
84     scanf("%s",s);
85     n=strlen(s);
86     build_sa();
87     scanf("%s",s1);
88     cout<<finds(s1);
89     return 0;
90 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值