Codeforces B. Segment Occurrences(陣列字首)
阿新 • • 發佈:2018-11-02
題意:給定一個主字串,和一子串,q次查詢,每次查詢一個區間,問子串在這個區間出現了幾次
題解:可以用字首來記錄當前下標之前,子串出現的次數,然後兩個字首陣列相減得到結果
(一開始我用的kmp去寫,不知道為什麼會超時,可能細節沒處理好,如果用kmp,也應該預處理記錄下每個區間子串出現的次數)
程式碼:
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <vector> #include <map> #include <queue> #define maxn 1005 #define INF 0x3f3f3f3f #define LL long long using namespace std; int n,m,k; string s,t; int pre[maxn]; int main() { cin>>n>>m>>k; cin>>s>>t; s=" "+s; t=" "+t; for(int i=1;i<=n;i++)//計算字首 { int flag=1; for(int j=1;j<=m;j++)//匹配子串來確定字首值 { if(s[i+j-1]!=t[j]) { flag=0; break; } } if(flag==1) { pre[i]=pre[i-1]+1; } else pre[i]=pre[i-1]; } for(int i=0;i<k;i++) { int l,r; cin>>l>>r; if(r-l+1<m) cout << 0 << endl; else cout << pre[r-m+1]-pre[l-1] << endl; } return 0; }
還有一種方法使用string類裡面的substr來做,s.substr(i,m)是取s中i下標開始的m個字元的字串
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <vector> #include <map> #include <queue> #define maxn 1005 #define INF 0x3f3f3f3f #define LL long long using namespace std; int n,m,k; string s,t; int ans[maxn]; int main() { cin>>n>>m>>k; cin>>s>>t; for(int i=0;i<n&&i+m<=n;i++) { if(s.substr(i,m)==t) ans[i]=1; } for(int i=0;i<k;i++) { int l,r; cin>>l>>r; int res=0; for(int i=l-1;i<=r-m;i++) { res+=ans[i]; } cout << res << endl; } return 0; }