复习了一遍最小表示法,在此做个整理
对于一个字符串求最小表示的算法流程如下:
1.将原字符串s复制一遍放在串尾
2.设i=0指向字符串头,j=i+1;
3.再设一个偏移量k=0,如果s[i+k]==s[j+k],k++;不相等让大的加上k+1;如果k大于等于字符串长度则说明字符串由同一个字母组成,如果i==j则其中一个加1
4.当i,j中一个大于字符串原长时返回另一个
时间复杂度为o(n)
其中第三步之所以让大的直接加上k+1是因为在0到k+1间都有对应的另一个指针指向的字符串比它小,所以一定不是最小表示
代码如下:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
string a,b;
int get_min(string x)
{
int i=0,j=1,len=x.size()/2;
while(i<len && j<len)
{
int k=0;
for(;x[i+k]==x[j+k];k++);
if(k>=len)break;
if(x[i+k]>x[j+k])i=i+k+1;
else j=j+k+1;
if(i==j)i++;
}
return min(i,j);
}
int main()
{
cin>>a>>b;
int len=a.size();
a=a+a;
b=b+b;
int i=get_min(a);
int j=get_min(b);
string ans1,ans2;
for(int k=0;k<len;k++)
ans1+=a[i+k],ans2+=b[j+k];
if(ans1==ans2)cout<<"Yes"<<endl<<ans1;
else cout<<"No";
}