「LOJ#103」子串查找 (Hash
阿新 • • 發佈:2018-10-17
ott 表示 pre lock -s 出現 提示 ica turn
題目描述
這是一道模板題。
給定一個字符串 A A A 和一個字符串 B B B,求 B B B 在 A A A 中的出現次數。AAA 和 BBB 中的字符均為英語大寫字母或小寫字母。
A A A 中不同位置出現的 B B B 可重疊。
輸入格式
輸入共兩行,分別是字符串 A A A 和字符串 B B B。
輸出格式
輸出一個整數,表示 B B B 在 A A A 中的出現次數。
樣例
樣例輸入
zyzyzyz
zyz
樣例輸出
3
數據範圍與提示
1≤A,B 1 \leq A, B1≤A,B 的長度 ≤106 \leq 10 ^ 6 ≤106,A A A、B B B 僅包含大小寫字母。
題解
題目說了是道KMP模板題qwq
1 /* 2 編號 題目 狀態 分數 總時間 內存 代碼 / 答案文件 提交者 提交時間 3 #224544 #103. 子串查找 Accepted 100 550 ms 2228 KiB C++ / 545 B qwerta 2018-10-10 18:01:154 */ 5 #include<iostream> 6 #include<cstdio> 7 using namespace std; 8 int nxt[1000003]; 9 int main() 10 { 11 string s,t; 12 cin>>s>>t; 13 int k=-1; 14 nxt[0]=-1; 15 int lens=s.length(),lent=t.length(); 16 for(int i=1;i<lent;++i) 17 {18 while(k!=-1&&t[i]!=t[k+1])k=nxt[k]; 19 if(t[i]==t[k+1])k++; 20 nxt[i]=k; 21 } 22 k=-1; 23 int ans=0; 24 for(int i=0;i<lens;++i) 25 { 26 while(k!=-1&&s[i]!=t[k+1])k=nxt[k]; 27 if(s[i]==t[k+1])k++; 28 if(k==lent-1){ans++;} 29 } 30 cout<<ans; 31 return 0; 32 }
然後還用來給Hash練了手(Hash首A!
/* 編號 題目 狀態 分數 總時間 內存 代碼 / 答案文件 提交者 提交時間 #224464 #103. 子串查找 Accepted 100 589 ms 2228 KiB C++ / 817 B qwerta 2018-10-10 17:06:38 */ #include<iostream> #include<cstdio> using namespace std; int main() { //freopen("a.in","r",stdin); string a,b; cin>>a>>b; unsigned long long h=0,hb=0; int lena=a.length(),lenb=b.length(); int mod=19260817,p=233;//膜數(bi~) // unsigned long long pown=1,base=p; int k=lenb-1; while(k) { if(k&1) pown=pown*base%mod; base=base*base%mod; k>>=1; } // for(int i=0;i<lenb;++i) hb=(hb*p+b[i])%mod; for(int i=0;i<lenb;++i) h=(h*p+a[i])%mod; int ans=0; if(hb==h)ans++; //cout<<h<<" "<<hb<<endl; for(int i=lenb;i<lena;++i) { h-=a[i-lenb]*pown%mod; h=((h+mod)*p+a[i])%mod; //cout<<h<<" "<<hb<<endl; if(h==hb)ans++; } cout<<ans; return 0; }
這是個什麽笨重代碼啊(自我吐槽
「LOJ#103」子串查找 (Hash