概述
最小(大)表示法是字符串问题中不同于匹配与失配的另一种O(n)的算法,它主要解决的是字符串的同构问题。将单个字符串循环左移右移算作该串的同构,最小(大)表示法能够在O(n)时间内求出这个串的所有同构串中的字典序最小的串的起始位置。由于代码简洁容易理解,因此在处理同类问题时往往比后缀数组以及各种匹配算法更加方便运用。
注意下标是从0开始的,返回的下标也从0开始
代码
最小表示法
1 int getMin(char str[],int len) 2 { 3 int i = 0,j = 1,k; 4 while(i < len && j < len) 5 { 6 for(k = 0;k < len;k++) 7 if(str[(i+k)%len] != str[(j+k)%len]) 8 break; 9 if(k >= len) break; 10 if(str[(i+k)%len] > str[(j+k)%len]) 11 { 12 if(i+k+1 > j) 13 i = i+k+1; 14 else 15 i = j+1; 16 } 17 else 18 if(j+k+1 > i) 19 j = j+k+1; 20 else 21 j = i+1; 22 } 23 // return i < j ? i : j; 24 return min(i,j); 25 }
最大表示法
1 int getMax(char str[],int len) 2 { 3 int i = 0,j = 1,k = 0; 4 while(i < len && j < len && k < len) 5 { 6 int t = str[(i+k)%len]-str[(j+k)%len]; 7 if(!t) 8 k++; 9 else 10 { 11 if(t > 0) 12 { 13 if(j+k+1 > i) 14 j = j+k+1; 15 else 16 j = i+1; 17 } 18 else 19 if(i+k+1 > j) 20 i = i+k+1; 21 else 22 i = j+1; 23 k = 0; 24 } 25 } 26 // return i < j ? i : j; 27 return min(i,j); 28 }