最小表示法
这是一种用于解决字符串最小表示问题的方法。
定义:字符串 \(S\) 的最小表示为与 \(S\) 循环同构 的所有字符串中字典序最小的字符串。
循环同构串:
设 \(S =\) bcad
,且设 \(S’\) 是 \(S\) 的循环同构的串。那么 \(S’\) 可以是 bcad
, cadb
, adbc
或者 dbca
即在字符串 \(S\) 中从 \(i \le 0\) 开始,从 \(i\) 循环到字符串末尾,再从头循环到 \(i\) ,所形成的字符就是 \(S\) 循环同构串。
又因为这样的同构串不止一个,所以我们要找出其中字典序最小的一个即为 \(S\) 的最小表示(即字符串从小到大排序,其中字典序最小的一个)。
主要是对暴力算法的 亿 点优化(
核心见 oi-wiki。
code
int minbs()
{
int i=0,j=1,k=0;//i,j为指针, k为匹配长度
while(i<n&&j<n&&k<n)
if(a[(i+k)%n]==a[(j+k)%n]) k++;//更新匹配长度
else
{
if(a[(i+k)%n]>a[(j+k)%n]) i+=k+1;
else j+=k+1;/*根据第k位大小跳转指针*/
if(i==j) i++;/*若跳转后指针相同,令其中一个+1以保证匹配的字符串不同*/
k=0;//把已匹配长度清0
}
return min(i,j);
}
\(\texttt{End.}\)