字符串匹配--最大最小表示法模板

概述

最小(大)表示法是字符串问题中不同于匹配与失配的另一种O(n)的算法,它主要解决的是字符串的同构问题。将单个字符串循环左移右移算作该串的同构,最小(大)表示法能够在O(n)时间内求出这个串的所有同构串中的字典序最小的串的起始位置。由于代码简洁容易理解,因此在处理同类问题时往往比后缀数组以及各种匹配算法更加方便运用。

注意下标是从0开始的,返回的下标也从0开始

代码

最小表示法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int getMin(char str[],int len)
{
int i = 0,j = 1,k;
while(i < len && j < len)
{
for(k = 0;k < len;k++)
if(str[(i+k)%len] != str[(j+k)%len])
break;
if(k >= len) break;
if(str[(i+k)%len] > str[(j+k)%len])
{
if(i+k+1 > j)
i = i+k+1;
else
i = j+1;
}
else
if(j+k+1 > i)
j = j+k+1;
else
j = i+1;
}
// return i < j ? i : j;
return min(i,j);
}

最大表示法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int getMax(char str[],int len)
{
int i = 0,j = 1,k = 0;
while(i < len && j < len && k < len)
{
int t = str[(i+k)%len]-str[(j+k)%len];
if(!t)
k++;
else
{
if(t > 0)
{
if(j+k+1 > i)
j = j+k+1;
else
j = i+1;
}
else
if(i+k+1 > j)
i = i+k+1;
else
i = j+1;
k = 0;
}
}
// return i < j ? i : j;
return min(i,j);
}