字符串算法总结
字符串 Hash
字符串 Hash:\(\text{Hash}(a)=\sum{a_i x^i} \bmod{p}\)。本質是一種進制的思想。
雙 Hash:保證正確性。
#define mod1 1000000007 #define mod2 1000000009ll n,p1[251],p2[251],p1b[251],p2b[251],s1[251],s2[251]; char c[251]; ll qpow(ll x,ll y,ll mod) {ll res=1;while(y) {if(y&1) res=res*x%mod;x=x*x%mod; y>>=1;}return res; } int main() {scanf("%lld",&n); scanf("%s",c+1);int l1,r1,l2,r2; scanf("%d%d%d%d",&l1,&r1,&l2,&r2);if((r1-l1)!=(r2-l2)) {printf("No"); return 0; }p1[0]=p2[0]=p1b[0]=p2b[0]=1;for (int i=1;i<=n;i++) {p1[i]=p1[i-1]*347%mod1;p2[i]=p2[i-1]*347%mod2;if(i==1) {p1b[i]=qpow(347,mod1-2,mod1);p2b[i]=qpow(347,mod2-2,mod2);} else {p1b[i]=p1b[i-1]*p1b[1]%mod1;p2b[i]=p2b[i-1]*p2b[1]%mod2;}s1[i]=(s1[i-1]+c[i]*p1[i])%mod1;s2[i]=(s2[i-1]+c[i]*p2[i])%mod2;}ll hash1,hash2,hash3,hash4;hash1=(s1[r1]-s1[l1-1]+mod1)%mod1*p1b[l1-1]%mod1;hash2=(s2[r1]-s2[l1-1]+mod2)%mod2*p2b[l1-1]%mod2;hash3=(s1[r2]-s1[l2-1]+mod1)%mod1*p1b[l2-1]%mod1;hash4=(s2[r2]-s2[l2-1]+mod2)%mod2*p2b[l2-1]%mod2;if(hash1==hash3&&hash2==hash4) printf("Yes %lld %lld %lld %lld",hash1,hash3,hash2,hash4)else printf("No %lld %lld %lld %lld",hash1,hash3,hash2,hash4);return 0; }Knuth–Morris–Pratt (KMP)
字符串匹配問題:給出文本串和模式串,求出模式串在文本串中所有出現的位置。
利用已經部分匹配這個有效信息,保持i指針不回溯,通過修改j指針,讓模式串盡量地移動到有效的位置。
當 \(P_k=P_j\) 時,有 \(\text{next}(j+1)=\text{next}(j) + 1\);
當 \(P_k\ne P_j\) 時,有 \(k=\text{next}(k)\)。
推薦:學習 KMP 看 Link ,復習 KMP 看 Link 。
char s[N], p[M]; int sl, pl;int nex[M];inline void getnex() { // 求前綴數組int k=-1, j=0; nex[0]=-1;while (j<pl) {if (k==-1 || p[j]==p[k]) { // 當兩個字符相等時要跳過if (p[++j]==p[++k]) nex[j]=nex[k]; else nex[j]=k;} else k=nex[k];} }inline void kmp() {int i=0, j=0; // i主串的位置,j模式串的位置while (i<sl && j<pl) {if (j==-1 || s[i]==p[j]) i++, j++; else j=nex[j]; // 當j為-1時,要移動的是i,當然j也要歸0if (j==pl) printf("%d\n", i-pl+1), j=nex[j];} }int main() {scanf("%s", s); scanf("%s", p);sl=strlen(s); pl=strlen(p);getnex();kmp();return 0; }字典樹 Trie
按前綴分類。
具體形態為一棵有根樹,每條邊上記錄一個字符,從根到一個節點路徑上所有字符接起來即這個節點所代表的字符串。實現時,我們對每個節點維護與字符集一一對應的兒子集合。插入字符串時,依次遍歷串中每個字符,并從根開始走每個字符對應的兒子,如果不存在則新建對應節點。時間復雜度為 字符串總長,空間復雜度為 字符串總長 \(\times\) 字符集。
?空間優化:用 map 來存儲兒子優化空間,代價是時間復雜度多一個 log。
轉載于:https://www.cnblogs.com/greyqz/p/string.html
總結
- 上一篇: qemu安装
- 下一篇: 【VMware】XP安装VMware T