后缀数组 魔板

为什么一开始要再字符串末尾多算个0呢
因为当开始分关键字比较的时候 最后要组成两个
字符所以要多个0 什么你有问我为什么填0
因为0小啊 先处理呗
虽然
sa是根据每个字符确定的大小
也就是排布的每个字符的排名
但是在初次求第二关键字排序的时候
可以使用sa的结论
首先吧sa后面的0排到最前面
那么0的数量 也就是从n-j到n开区间 都是0作为第二关键字的区域
也就是这句话

for(p=0,i=n-j;i<n;i++) y[p++]=i;

这一句

for(int i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;

是表示
当0已经排完了
现在再把非0的排进去
如何排进去呢?
我们看
我们从1-n开区间枚举
如果sai大于等于j说明排到第i位的后缀的位置是大于等于j,大于等于
现在的枚举长度的
那么就把他们放到y
也就是第二关键字排名数组中 并将其值记录为本字符串的开始位置sa[i]-j;

for(i=0;i<n;i++) wv[i]=x[y[i]];

由于y数组中是按照第二关键字排序后存放的开始位置的数组
那么当我按照y从x数组中把值提取出来付给wv数组时 就相当于
把要比较的长度为2的倍增一倍的数组放到wv中去了
接下来就用下面的四个for循环来按第一关键字对合并后的字符串进行排序,最后更新sa道理同上面对字符串第一个字符进行排序的四个for循环。

    for(i=0;i<m;i++) ws[i]=0;//将新的桶清0 1for(i=0;i<n;i++) ws[wv[i]]++;//2for(i=1;i<m;i++) ws[i]+=ws[i-1];//3for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];//4

1:盛放j=1 长度为2 由于是按照低位排过序后的数组放入的wv 而wv存放的是第一关键字的值 为后续排序做准备
2:按照第一关键字的顺序将其装桶标记
3:按照第一关键字的顺序计算前缀和
4: 对于每个wv 是先按照第二关键字排序顺序装入的ws 也就是基数排序的本质
此时在2句又按照第一关键字的值(存储的是第一关键字的值)排好了序
每次– 逆序处理
此时得到的sa数组 就是一个在以第一二关键字合并的情况下按照其大小按照加上第一关键字的新顺序从高到低
讲y数组(记录的是初始位置)的值付给sa
表示字符串排序第i个位于y[i]

for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}一个cmp

最后再来看下cmp函数的作用
如果y也就是原来的x数组下a位置的和b位置的相等 并且第二关键字也相等
那么就会返回1
返回1就会让这段字符的实质排名为p-1 返回0表示不相等那么就说明两段不相等
让其等于p 则两段字符的排名相同
最终的p值 就代表我一共有排到了几 其中有可能有排名相等的项
那么这个p也就是其中下一循环的m值 也就是下一次循环
其中每个单关键字的排名不会超过m 存储到x数组中

魔板:


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
int n,m;
int *t,sa[1010],a[1010],b[1010],ms[1010],mv[1010];
char aa[50];
void LSD(int n,int *x,int *y,int *Ws,int *wv){m = 130;for(int i=0;i<m;i++)Ws[i]=0;for(int i=0;i<n;i++)Ws[x[i]=aa[i]]++;for(int i=1;i<m;i++)Ws[i]+=Ws[i-1];for(int i=n-1;i>=0;i--)sa[--Ws[x[i]]]=i;for(int p=1,m,j=1;p<n;j<<=1,m=p){p=0;for(int i=n-j;i<n;i++)y[p++]=i;for(int i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;for(int i=0;i<n;i++)wv[i]=x[y[i]];for(int i=0;i<m;i++)Ws[i]=0;for(int i=0;i<n;i++)Ws[wv[i]]++;for(int i=1;i<m;i++)Ws[i]+=Ws[i-1];for(int i=n-1;i>=0;i--)sa[--Ws[wv[i]]]=y[i];int i;for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)x[sa[i]] =(y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]) ?p-1:p++;}return;
}
int main()
{scanf("%s",aa);LSD(strlen(aa)+1,a,b,ms,mv);for(int i=0;i<strlen(aa);i++)printf("%d ",sa[i]);puts("");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

几何运算

几何运算 .概念 几何运算就是改变图像中物体对象&#xff08;像素&#xff09;之间的空 间关系。 从变换性质来分&#xff0c;几何变换可以分为图像的位置变换 &#xff08;平移、镜像、旋转&#xff09;、形状变换&#xff08;放大、缩小&#xff09;以 及图像的复等合变换…

vmware创建虚拟机并安装centos7系统

一、vmware创建虚拟机 1、添加一个全新的虚拟机 2、以典型的方式创建虚拟机&#xff0c;然后下一步 3、选择稍后安装操作系统&#xff08;这样我们等下可以自由选择操作系统&#xff09;&#xff0c;然后下一步 4、选择客户及操作系统类型及版本&#xff08;由于我这里将安装的…

MySQL学习笔记3——JDBC

目录JDBC简介数据库驱动JDBC第一个JDBC程序JDBC中各对象详解statement对象包装成工具类SQL注入问题PreparedStatement对象使用IDEA连接数据库JDBC操作事务数据库连接池DBCP需要用到的JAR包DBCP配置文件工具类测试代码C3P0需要用到的JAR包C3P0配置文件工具类测试代码结论JDBC简介…

[Leedcode][JAVA][第15题][三数之和][数组][双指针]

【问题描述】[中等] 给你一个包含 n 个整数的数组 nums&#xff0c;判断 nums 中是否存在三个元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;请你找出所有满足条件且不重复的三元组。注意&#xff1a;答案中不可以包含重复的三元组。 示例&#…

HDU 5882 Balanced Game 分析+欧拉图

题意 就是把判断有五个姿态的剪子包袱锤游戏其中能否平局分析 。。。。code ## /*本题的正确逻辑是分析出图中要求的是个欧拉图因为每个点的入度等于出度每个点的攻防数目都一样所以可以把当前有向欧拉图 转化为无向欧拉图当且仅当 其中没有奇数定点的时候所以这道题 ~ */#i…

Yarn的三种资源调度机制

在企业中并不是只有一个人来执行MapReduce程序单独使用Yarn的资源&#xff0c;实际开发中&#xff0c;会有很多人一起使用Yarn这个资源&#xff0c;如果每个人都提交了job&#xff0c;这个时候Yarn就需要进行调度去分配资源给job&#xff0c; 下面三种调度机制&#xff0c;默认…

Java学习笔记9-1——JavaWeb

目录HTTPHTTP请求HTTP响应ServletServlet原理Mapping问题ServletContext获取ServletContext对象ServletContext应用HttpServletResponse下载文件验证码功能实现重定向HttpServletRequestCookie和Session会话CookieSession&#xff08;重点&#xff09;对比ServletContextJSPJSP…

HDU - 5878 A - I Count Two Three H 技巧枚举

题意 输入 t (1≤t≤500000), the number of test cases. t test cases follow. Each test case provides one integer n (1≤n≤109).让我们不小于n的最小的x满足 x2^a*3^b*5^c*7^d 分析 这道题其实就是个枚举 但是不能随便枚举 比如 如果向这样枚举的话scanf("%lld&q…

[剑指offer][JAVA]面试题第[22]题[j剑指offer][双指针][快慢指针]

【问题描述】[中等] 输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表的尾节点是倒数第1个节点。例如&#xff0c;一个链表有6个节点&#xff0c;从头节点开始&#xff0c;它们的值依次是1、2、3、4…

灰度重采样(Gray Resampling

插值方法 nearest——最邻近点插值。它根据已知两点间的插值 点和这两已知点间位置的远近来进行插值&#xff0c;取较近已知 插值点处的函数值作为未知插值点处的函数值。 linear——线性插值。它将相邻的数据点用直线相连&#xff0c; 按所生成的直线进行插值。 spline——…

java调用python脚本

java调用python脚本 常见的java调用python脚本方式 通过jython.jar提供的类库实现 &#xff08;不建议使用&#xff0c;因为会报module没有找到的错误&#xff0c;总之就是很蛋疼&#xff0c;要设置一系列的参数&#xff09;通过Runtime.getRuntime()开启进程来执行脚本文件&am…

空间变换方法

空间变换方法可分为简单变换和控制点变换两种方法&#xff0c; 主要介绍了简单变换 法&#xff0c;这里再补充控制点变换方法。 在许多图像处理的应用中&#xff0c;所需的空间变换都很复杂&#xff0c;不是只通过简单的平移、旋转和 缩放等能解决的&#xff0c;而要通过各种不…

[剑指offer][JAVA]面试题第[24]题[反转链表][递归][双指针][头插法]

【问题描述】[中等] 定义一个函数&#xff0c;输入一个链表的头节点&#xff0c;反转该链表并输出反转后链表的头节点。示例:输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL限制&#xff1a;0 < 节点个数 < 5000【解答思路】 1. …

AC自动机模板

const int maxn 1000005;//定义所需要最大长度 struct Aho{struct state{int next[26];//trie树结构int fail,cnt;//失配指针和表示当前点作为结束点的标记}st[maxn];int size;//定义当前一共有多少个点queue<int>q;//层序遍历序列void init(){for(int i0;i<maxn;i){…

【解决问题】useBean类属性[com.cheng.pojo.People]的值无效导致HTTP500问题

先上实体类代码的前半部分&#xff1a; 这是出现问题时的&#xff1a; package com.cheng.pojo;public class People {private int id;private String name;private int age;private String address;public People(int id, String name, int age, String address) {this.id i…

python学习day32 黏包 struct模块

为什么会出现黏包问题&#xff1f; 首先只有在TCP协议中才会出现黏包现象 是因为TCP协议是面向流的协议 在发送的数据 传输过程中 有缓存机制 来避免数据丢失 因此 在连续发送小数据的时候 以及接收大小不符的时候都容易出现黏包现象 本质还是因为我们在接受数据的时候不知道发…

HDU-5935 Car 逆推 贪心 精度

题意 1 主人公从0开始开始跑 2 使用速度非递减技能 3 警察记录下了多个整数时间点他的位置 整数时间点不明确 让我们求主人公所花费的最小时间跨越过最后一个位置点 分析 本体选用逆推处理 为啥用逆推 因为速度是非递减的 如果从前面推 会导致不断重复修改 前面的时间 时间不…

[Leedcode][JAVA][第1300题][转变数组后最接近目标值的数组和][前缀和][二分法][暴力]

【问题描述】[中等] 给你一个整数数组 arr 和一个目标值 target &#xff0c;请你返回一个整数 value &#xff0c;使得将数组中所有大于 value 的值变成 value 后&#xff0c;数组的和最接近 target &#xff08;最接近表示两者之差的绝对值最小&#xff09;。如果有多种使得…

线性系统的基本理论与运算

线性系统的基本理论与运算 线性系统与非线性系统 线性系统的基本理论 二维线性移不变系统 线性移不变系统 如果一个系统既是线性系统&#xff0c;又是移不变系统&#xff0c;则该系 统是线性移不变系统。