日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符串算法总结

發布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符串算法总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符串 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

總結

以上是生活随笔為你收集整理的字符串算法总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。