最小(大)表示法讲解

来源:互联网 发布:数据加密标准des是对称 编辑:程序博客网 时间:2024/06/13 21:59

参考文章:http://blog.csdn.net/u012501262/article/details/21823363

引子

首先有一个字符串s,我们可以对他进行操作,每次操作都可以将第一个字符移动到最后一个字符。我们要求解经过n次操作后,得到的字典序最小的字符串是什么。

一.朴素算法

朴素算法利用两个指针i,j。初始i = 0,j = 1。i 为最小的字符串的开头位置

a.当s[i] > s[j]  时

i = j;//因为j是更小的

j++;

b.当s[i] < s[j]时

j ++;

c.当s[i] == s[j] 时

k = 0

n = strlen(s)

while(k < n)

{

    if(s[(i + k)% n] < s[(j + k) % n])

    j ++;

   if(s[(i + k) %n] > s[(j + k) %n])

     i  = j,j ++;

}

二.最小表示法的实现

就是在朴素的基础上进行一些更改

仍旧是设置两个指针i = 0,j = 1.但这两个指针都是可以作为指向最小位置的指针,而先到达n的不是最小位置。如果k到达n,意味着整个字符串都相等,那么最小位置就是0

从k = 0 开始,如果s[(i + k) %n] == s[(j + k) %n],就一直k ++

   if(s[(i + k) %n] > s[(j + k) %n])

i = i + k + 1(也就是从i 到 i + k都不可能是最小的位置)

设i'属于[i,i+k]

有s[i',i + k - 1] == s[i' + j - i,j + k - 1]而s[i + k] > s[j + k]

另一面同理。记得k清零

如果i == j,j++。错开

代码如下:

int minandmax(int x){    int i = 0,j = 1,k = 0;    int t;    while(i < n && j < n && k < n)    {        t = s[(i + k) % n] - s[(j + k) %n];        if(t == 0)        {            k ++;        }        else        {            if(t > 0)            {                i = i + k + 1;            }            else            {                j = j + k + 1;            }        }        if(i == j)        {            j ++;        }        k = 0;    }}return min(i,j);}





0 0