最小表示法

最小表示法

什么是最小表示法,就是说给定一个字符串,每次将字符串的最后一位放在最前面组成新的字符串,叫做循环同构,而这些字符串里面字典序最小的就是最小表示
比如,设s=“abca” 那么他的循环同构字符串有:abca,aabc,caab,bcaa,那么s的最小表示就是aabc
那么我们怎么求呢?最简单的就是朴素算法,按照定义以此比较这个字符串的字典序
那么如何使用最小表示法?

		1.初始化i=1,j=2
		2.通过扫描的方式比较b[i]与b[j]两个循环同构串
		(1)如果扫描了n个字符仍然相等,说明s由1种字符构成,任意b[i]都是他的最小表示法
		(2)在i+k与j+k发现不相等
		如果ss[i+k]>ss[j+k]那么直接i=i+k+1;如果i=j那么i++
		如果ss[i+k]<ss[j+k]那么直接j=j+k+1;如果i=j那么j++

其实最小表示法这种算法比较厉害,比较聪明,发现ss[i+k]>ss[j+k]就不做任何的多余的操作,直接跳过,和KMP还是有一点的像的,也就是说及时排除多余现象,最后保存答案

int n;
for(int i=1;i<=n;i++)
{
	s[n+i]=s[i];//预处理
 } 	
int i=1,j=2,k;//执行第一步
while(i<=n&&j<=n)
{
	for(k=0;k<=n&&s[i+k]==s[j+k];k++);
	//找到不相等的地方
	if(k==n) break;//只有一个字符构成
	if(s[i+k]>s[j+k])
	{
		i=i+k+1;//及时过滤多余现象
		if(i==j) i++; 
	 }
	 else
	 {
	 	j=j+k+1;
		if(i==j) j++; 
	  } 
 }
 ans=min(i,j);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值