最小(大)表示法详解。。。。。

参考::https://blog.csdn.net/CillyB
参考::https://blog.csdn.net/li1615882553

  • 算法用途**
    我在一个hash的题目中了解到这个算法,还是很简单,具体描述如下:有一个首位相连的字符串,我们要寻找一个位置,从这个位置向后形成一个新字符串,我们需要使这个字符串字典序最小。

  • 算法解释
    我们这里要i = 0,j = 1,k = 0,表示从i开始k长度和从j开始k长度的字符串相同(i,j表示当前判断的位 置)
    当我们str[i] == str[j]时,根据上面k的定义,我们的需要进行k+1操作
    当str[i] > str[j]时,我们发现i位置比j位置上字典序要大,那么不能使用i作为开头了,我们要将i向后移动,移动多少呢?有因为i开头和j开头的有k个相同的字符,那么就执行 i = i + k +1
    相反str[i] < str[j]时,执行:j = j + k +1
    最终i和j中较小的值就是我们最终开始的位置

  • 举个例子
    设S=bcad,且S’是S的循环同构的串。S’可以是bcad或者cadb,adbc,dbca。而且最小表示的S’是adbc。
    对于字符串循环同构的最小表示法,其问题实质是求S串的一个位置,从这个位置开始循环输出S,得到的S’字典序最小。
    一种朴素的方法是设计i,j两个指针。其中i指向最小表示的位置,j作为比较指针。

    令i=0,j=1
    如果S[i] > S[j] i=j, j=i+1
    如果S[i] < S[j] j++
    如果S[i]==S[j] 设指针k,分别从i和j位置向下比较,直到S[i] != S[j]
    如果S[i+k] > S[j+k] i=j,j=i+1
    否则j++
    返回i

模板


    int Get_min()
{
    int n = strlen(s);
    int i = 0,j = 1,k = 0,t;
    //表示从i开始k长度和从j开始k长度的字符串相同
    while(i < n && j < n && k < n)
    {
        t = s[(i+k)%n] - s[(j+k)%n];
        //t用来计算相对应位置上那个字典序较大
        if(!t) k++;//字符相等的情况
        else
        {
            if(t > 0) i += k+1;//i位置大,最大表示法: j += k+1
            else j += k+1;//j位置大,最大表示法: i += k+1
            if(i == j) j++;
            k = 0;
        }
    }
    return i >j ?j :i;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值