最小表示法與kmp演算法一樣都可以解決字串匹配問題,但效率更高,**短,作用更大。
最小表示法就是乙個字串的最小字典序。
怎麼求乙個字串的最小字典序呢?
首先將這個字串擴充套件一倍(建設存在d陣列裡),然後我們用三個指標i=0,j=1,k=0,來尋找最小字典序的開頭字母,為了優於kmp,我們要做到o(n)。
i表示假設最小字典序為d[i];
j為輔助變數,用於證明i是不是最小字典序的開頭;
k表示當以i開頭和與j開頭的字串從第乙個字母開始重複的部分的個數。
每次讓k=0,若d[i+k]==d[j+k]就k++;(直到不滿足條件再做下面的步驟)
若d[i+k]>d[j+k]則i=i+k+1;否則j=j+k+1;(想想為什麼?)當i與j相等時,j++;
當i,j,k中有乙個的長度大於原長度時則退出,答案即為min(i,j)。
總複雜度為o(n)。
poj1509:
給n個字串輸出每個字串的最小字典序的開頭字母在原字串中的位置。
#include
#include
#include
#define inf 200005
#define rep(i,l,r) for(i=l;i<=r;i++)
int n,m,t;
char a[inf];
char b[inf];
char c[inf],d[inf];
int l=0,l1=0;
int init()
return0;}
int min0(int a,int b)
int work()
if(i>j)i=j;
return i;
}int main()
還有一題,給你兩個字串,判斷它們的最小字典序是否相等。(資料自己出吧。。。qaq)
#include
#include
#include
#define inf 20000005
#define rep(i,l,r) for(i=l;i<=r;i++)
int n,m;
char a[inf];
char b[inf];
char c[inf],d[inf];
int l=0,l1=0;
int init()
j++;
}if (step)printf("no\n");
else
printf("\n");
return0;}
int min0(int a,int b)
int work2()
if(i>j)i=j;
rep(o,0,l-1)
c[o]=b[(i+o)%l];
return i;
}int work()
if(i>j)i=j;
rep(o,0,l-1)
d[o]=a[(i+o)%l];
return i;
}int main()
最後吐糟一句,其實最小表示法在很多地方都很有用。。。(下次再補上來,sorry) 最小表示法
最小表示法就是找出字串s的的迴圈同構串中字典序最小的乙個。那麼什麼是迴圈同構串呢。是 設s bcad 且s 是s 的迴圈同構的串。s 可以是 bcad 或者cadb,adbc,dbca 即在字串s中從i 0開始,從i迴圈到字串末尾,再從頭迴圈到i,所形成的字元就是s迴圈同構串。因為這樣的同構串不止乙...
最小表示法
最小表示法 思想 在字串迴圈同構問題中的應用 摘自周源的ppt 前言 最小表示法 比起動態規劃 貪心等思想,在當今競賽中似乎並不是很常見。但是在解決判斷 同構 一類問題中卻起著重要的作用。本文即將討論字串中的同構問題,如何巧妙地運用最小表示法來解題呢,讓我們繼續一起思考吧。到底什麼是迴圈同構的字串呢...
最小表示法
最小表示法是判斷同構的一種方法,和hash一樣都有字串和樹的兩種 給定乙個字串,把它首尾相連形成字元環,然後從某個點開始的字串字典序最小,為該字串的最小表示 用兩個指標i,j,且k 0,然後若x i k x j k 則k 直到不等 若x i k x j k 那麼i k 1 x i k x j k 說...