首页 > 其他分享 >字符串——最小表示法

字符串——最小表示法

时间:2024-05-23 12:31:20浏览次数:23  
标签:同构 复杂度 最小 else 表示法 sec 字符串 mathcal

字符串——最小表示法

定义

在字符串 \(S\) 的所有,与其循环同构的字符串 \(T\) 中,字典序最小的一个。

循环同构:字符串 \(S\) 循环移位,所有可以得到的字符串 \(T\) 与 \(S\) 循环同构。

暴力

枚举与 \(S\) 循环同构的每一个字符串,比较其字典序。

枚举复杂度 \(\mathcal O(n)\),字典序比较复杂度 \(\mathcal O(n)\),整体复杂度 \(\mathcal O(n^2)\)。

优化

可以先将字符串拼接一倍,注意到最小表示一定是以一个 \(k\) 开头的长度为 \(n\) 的字串。

于是,可以用两个指针,分别表示两个比较优化的解,然后考虑扩展。

对于当前的,如果相同,那么扩展长度;如果不同,那么长度清零,然后考虑移动指针。

对于大的,考虑移动,指针向后移动一位,进行下一轮判断。

借用 OI-Wiki 的代码,

k, i, j = 0, 0, 1
while k < n and i < n and j < n:
    if sec[(i + k) % n] == sec[(j + k) % n]:
        k += 1
    else:
        if sec[(i + k) % n] > sec[(j + k) % n]:
            i += 1
        else:
            j += 1
        k = 0
        if i == j:
            i += 1
i = min(i, j)

时间复杂度 \(\mathcal O(n^2)\),对于随机数据还可以。

最小表示法

考虑继续优化,注意到如果找到了一组不同的,那么大的可以直接移动下去。

因为对于前面的每一个字串,这一个大的每一个字串都可以唯一的对应一个更优的字符串。

代码依旧借用 OI-Wiki 的:

k, i, j = 0, 0, 1
while k < n and i < n and j < n:
    if sec[(i + k) % n] == sec[(j + k) % n]:
        k += 1
    else:
        if sec[(i + k) % n] > sec[(j + k) % n]:
            i = i + k + 1
        else:
            j = j + k + 1
        if i == j:
            i += 1
        k = 0
i = min(i, j)

然后贴一下我的代码:

template<typename tp>
basic_string<tp> mcs(basic_string<tp> a) {
	int n = a.size(); a = a + a;
	int i = 0, j = 1;
	for (int k = 0; k < n && i < n && j < n; ) {
		const auto ii = a[i + k], jj = a[j + k];
		if (ii == jj) continue(++k);
		else if (ii > jj) i = i + k + 1;
		else j = j + k + 1;
		k = 0; if (i == j) ++j;
	}
	return a.substr(min(i, j), n);
}

标签:同构,复杂度,最小,else,表示法,sec,字符串,mathcal
From: https://www.cnblogs.com/RainPPR/p/18208156

相关文章

  • 最小度限制生成树
    先看这篇题解其中主要是这两个部分的证明也就说明了为什么可以使用wqs二分这篇文章还没有详细看,有空了详细看一下(这篇文章的方法也没看,还有洛谷第一篇题解)......
  • 逗号分开的字符串,统计个数从高到底排序
    usesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,System.RegularExpressions, functionCompareStrings(List:TStringList;Index1,Index2:Integer):Integer;beginResult:=StrToInt(List.ValueF......
  • 总结全网C#取随机数方法(整型,浮点型,字符串)
    原文链接:https://blog.csdn.net/m0_65636467/article/details/127770112C#取随机数(Random篇)一、整数随机数//10以内的随机整数Randomrd=newRandom();intn=ran.Next(10);//1-100的随机整数intp=rd.Next(1,100);//大于等于1小于100的整数intNext(intmi......
  • 力扣-1209. 删除字符串中的所有相邻重复项 II
    1.题目题目地址(1209.删除字符串中的所有相邻重复项II-力扣(LeetCode))https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string-ii/题目描述给你一个字符串 s,「k倍重复项删除操作」将会从s 中选择 k 个相邻且相等的字母,并删除它们,使被删去的字符串的......
  • 使用Chrome 开发者工具提取对应的字符串
    最近在查看一个API的数据,效果很好,但是里面只有一部分我想要的内容 如果是简单一点的可以直接获取如下比如我想要提取返回的代码中关键的字符串:"video":"这里的内容"//定义一个正则表达式来匹配'"video":"链接"'格式的字符串varregex=/"video":\s*"([^"]+)"/gi;......
  • 最小生成数——prim以及Kruskal
    最小生成数——prim以及Kruskal1.关于prim算法原理板子代码解释板子题2.关于Kruskal算法原理板子板子题prim原理:对树中的点进行遍历,存点构成一个新图,每次找离新图最近的点加入新图。代码实现解释将起始点的一系列临边的点赋值for(inti=head[......
  • 「网络流浅谈」最小割的模型
    最大权闭合子图引入Introduction闭合子图指对于子图\(G=(V,E)\),\(\forallu\inV,(u,v)\inE\),都有\(v\inV\)。最大权闭合子图无非就是对于所有的闭合子图\(G\)中\(\sum_{u\inV}w_u\)最大的闭合子图。对于这个图中,闭合子图有哪些呢?红色框圈画出的即为\(1\)个......
  • CSP历年复赛题-P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题
    原题链接:https://www.luogu.com.cn/problem/P1029题意解读:已知x,y,求有多少对p、q,使得p、q的最大公约数为x,最小公倍数为y。解题思路:枚举法即可。枚举的对象:枚举p,且p必须是x的倍数,还有p<=yq的计算:q=x*y/p,q要存在,必须x*y%p==0,且gcd(p,q)==x100分代码:#include......
  • Mybaits使用SQL拦截器实现字符串修剪
    概述一般情况下,保存到数据库中的字符串类型的数据,我们一般都不希望它前后带着空格,类似于"哈哈哈"。在业务中,如果每一个保存到数据库中的SQL都去对字符串参数进行trim的操作,这是很繁琐的,且容易漏掉。解决方案使用Mybatis的拦截器,拦截每一个SQL,针对SQL中的字符串参数进行tr......
  • 【Halcon】实现分离通道、创建矩形、获取灰度级、求最大最小均值、求大于某一灰度级的
    read_image(Image,'D:/image/123.jpg')rgb1_to_gray(Image,GrayImage)gen_rectangle1(Rectangle,100,100,200,200)rectangle1_domain(GrayImage,ImageReduced,100,100,200,200)crop_domain(ImageReduced,ImagePart)get_region_points(ImageP......