字符串的最小表示法
对于一个字符串,可将它最后一位放到第一位来,依次类推,共n种变形,n为字符串长度
例如:s="00ab"变形有(省略引号)b00a ab00 0ab0一共4种
那么找到其中字典序最小的一个,用的算法便是这个
#include<bits/stdc++.h>
using namespace std;
int min_express(char* str){
int len=strlen(str),i=0,j=1,k=0; //len串长,两个指针IJ,k表示当前已匹配串长
while(i<len&&j<len&&k<len){ //三个指针都未达串长
int t=str[(j+k)%len]-str[(i+k)%len];//以ij为左界,往右走K步的右界是否相等
if(!t) k++; //T为空即两个字符相等,则K步长加大,直至不同为止
else{
if(t<0) i=i+k+1; //因为是j-i,t<0就是j+k位字符较小,i不会是最小那么就更新
else j=j+k+1; //同理i小就更新j
if(j==i) j++; //如果ij更新完是同一个字符,j就加1,两个左界要不一样
k=0; //下一次又是从0步长开始
}
cout<<i<<' '<<j<<endl;
}
return min(i,j);//其实输出I就可以了
}
int main(){
char s[100];cin>>s;
cout<<min_express(s)<<endl;
return 0;
}
/*
babaa
3(表示在下标为2的位置开始的串是最小的(循环串,即aabab)
note:
i j
1 2首先B比A大I到下标1,J到下标2,K是0
1 3然后A比B小J到下标3,K是0
1 3然后A与A相等,K变1
3 4然后B比A大I到下标3,J到下标4,K变0
3 4然后A与A相等,k变1
3 6最后A比B小j到下标5达到LEN,K变0
*/