1. 程式人生 > >Codeforces B. Segment Occurrences(陣列字首)

Codeforces B. Segment Occurrences(陣列字首)

題意:給定一個主字串,和一子串,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;
}