1. 程式人生 > >字串Hash總結模板

字串Hash總結模板

字串匹配

     感覺用字串hash 可以水過很多字串匹配的問題,(KMP太頭疼了)

實現方法:

    計運算元串的hash值,在長串中從第一位開始,往後延伸到和子串同樣長度,然後算出這段字元的hash值,看是否和子串的hash值相等。

題目連結

                  

模板

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000500

using namespace std;
typedef unsigned long long ull;
const int base=133;
ull po[maxn];
ull a[maxn],b[10005];
ull ha[maxn];

ull code(int l,int r)
{
     return ha[r]-ha[l-1]*po[r-l+1];
}
int main(void)
{
     int t,m,n;
     ull hb;
     scanf("%d",&t);
     po[0]=1;
     for(int i=1;i<maxn;i++)
     {
          po[i]=po[i-1]*base;//記得乘上相應的po值
     }
     while(t--)
     {
          memset(ha,0,sizeof(ha));
          scanf("%d%d",&n,&m);
          ha[0]=0;//如果子串的長度不是固定的不能把ha[]的值設為0,因為掩蓋了長度資訊
          for(int i=1;i<=n;i++)
          {
               scanf("%lu",&a[i]);
               ha[i]=ha[i-1]*base+a[i];
          }
          hb=0;
          for(int i=1;i<=m;i++)
          {
               scanf("%lu",&b[i]);
               hb=hb*base+b[i];//算出b的雜湊值
          }
          int t=-1;
          for(int i=1;i<=n-m+1;i++)
          {
               if(code(i,i+m-1)==hb)
               {
                    t=i;
                    break;
               }
          }
          printf("%d\n",t);
     }
     return 0;
}

與DP結合

例題:題目連結

題目大意:

     上面串A是原文,下面的子串B表示這串字元有兩個意思,問你原文可能會有多少個意思。

題目思路:

用dp[i]表示以i結尾的原文會有多少個意思,那麼當以第i位結束的長度為lb=len(B)的字串和B匹配的話,

dp[i]=dp[i-lb]+dp[i-1];①

否則dp[i]=dp[i-1]②

比如A為hehehe,B為hehe

顯然我們應該從A的第四位開始迴圈判斷,往前數4個數字(B的長度),如果和B匹配就執行①,否則執行②

至於判斷是否匹配,可以用字串雜湊,相當快~

程式碼:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#define maxn 100005
#define mod 1000000007

using namespace std;
typedef unsigned long long ull;
const int base=133;
ull po[maxn];
ull dp[maxn];
ull ha[maxn];
char a[maxn],b[maxn];

ull code(int l,int r)
{
     return ha[r]-ha[l-1]*po[r-l+1];
}
int main(void)
{
     int t;
     scanf("%d",&t);
     po[0]=1;
     for(int i=1;i<maxn;i++)
     {
          po[i]=po[i-1]*base;
     }
     int kase=0;
     while(t--)
     {
          memset(dp,0,sizeof(dp));
          memset(ha,0,sizeof(ha));
          //
          scanf("%s",a+1);
          scanf("%s",b+1);
          int la=strlen(a+1);int lb=strlen(b+1);
          ull hb=0;
          for(int i=1;i<=lb;i++)
          {
               hb=hb*base+b[i]-'a';//計算出b的雜湊值
          }
          //開始處理a
          ha[0]=0;
          for(int i=1;i<=la;i++)
               ha[i]=ha[i-1]*base+a[i]-'a';
          //
          for(int i=0;i<lb;i++)
               dp[i]=1;
          for(int i=lb;i<=la;i++)
          {
               ull hs=code(i-lb+1,i);
               if(hs!=hb)
                    dp[i]=dp[i-1]%mod;
               else
                    dp[i]=(dp[i-lb]%mod+dp[i-1]%mod)%mod;
          }
          printf("Case #%d: %lu\n",++kase,dp[la]);
     }
     return 0;
}

呼呼

相關推薦

字串Hash總結模板

字串匹配      感覺用字串hash 可以水過很多字串匹配的問題,(KMP太頭疼了) 實現方法:     計運算元串的hash值,在長串中從第一位開始,往後延伸到和子串同樣長度,然後算出這段字元的hash值,看是否和子串的hash值相等。 題目連結        

cf244D. Match & Catch 字串hash模板)或 字尾陣列。。。

可以用各種方法做,字串hash,字尾陣列,dp,拓展kmp,字典樹。。。 字串hash(模板) BKDR Hash Function : // BKDR Hash Function unsigned int BKDRHash(char *str) {

字串Hash模板

博主連結 #include<stdio.h> #include<bits/stdc++.h> #define ll long long int using namespace std; ll gethash(char *s,int m){

一維字串hash模板

#include<bits/stdc++.h> #define LL long long #define INF 0x3f3f3f3f #define INFLL 0x3f3f3f3f3f

字串hash補充(快速冪模板

題目: 字串的雜湊就是通過某些對映關係,將字串對映到數字上去方便進行比較。 比如二進位制數110110,我們知道這個數的十進位制是 54 基於同樣思路,我們可以定義這樣的一個雜湊函式: 雜湊函式

字串學習總結Hash & Manacher & KMP)

# 前言 終於開始學習新的東西了,總結一下字串的一些知識。 ## NO.1 字串雜湊(Hash) ### 定義 即將一個字串轉化成一個整數,並保證字串不同,得到的雜湊值不同,這樣就可以用來判斷一個該字串是否重複出現過。 所以說$Hash$就是用來求字串是否相同或者包含的。(包含關係就可以列舉區間,但是通常

hash模板

clas ostream sign 模板 快速 space char string lin           hash 功能:  hash一般用於快速判斷兩個或多個字符串是否匹配。 實現 : 想一想,如果比較兩個數子的話是很方便的很快,那麽我們把整個字符串看成一個大

ural1989 單點更新+字串hash

正解是雙雜湊,不過一次雜湊也能解決。。 然後某個數字就對應一個字串,雖然有些不同串對應同一個數字,但是概率非常小,可以忽略不計。從左到右、從右到左進行兩次hash,如果是迴文串,那麼對應的整數必定存在某種關係(可以理解成相等),對於更新操作,就是單點更新。 #include<iostream&

ES6字串擴充套件(模板字串

es5中的多行字串和變數拼接: let num = 10, price = 100; let str = "我們現在有"+num+"個人\ 來買蘋果,一斤蘋果10元錢,\ 他們每人買一斤,那麼總價是"+price+"元。" //let

一些常用 js 對於 陣列 字串 方法總結

一 、陣列concat連線 var arrayA = [1,2,3] var arrayB = [4,5,6] var arrayC = [7,8,9] console.log(arrayA.concat(arrayB)) //(6) [1,2,3,4,5,6] console.log(

《JAVA》字串操作總結

  public String concat(String str) 該方法的引數為一個String類物件,作用是將引數中的字串str連線到原來字串的後面. public int length() 返回字串的長度,這裡的長度指的是字串中Unicode字元的數目.

Power Strings---字串hash

問題 C: 【雜湊和雜湊表】Power Strings 時間限制: 1 Sec  記憶體限制: 128 MB 提交: 38  解決: 18 [提交] [狀態] [討論版] [命題人:外部匯入] 題目描述 Gi

js字串方法總結

字元方法:       charAt (返回指定位置的字元)       charCodeAt(返回unicode碼) 拼接方法       concat 任意多個引數  可使用 + 代替

Mysql字串擷取總結:left()、right()、substring()、substring_index()

Mysql字串擷取總結:left()、right()、substring()、substring_index()   轉載:https://www.cnblogs.com/heyonggang/p/8117754.html 在實際的專案開發中有時會有對資料庫某欄位擷取部分的需求

python 字串總結

大小寫轉換 str.capitalize() 將首字母轉換成大寫,需要注意的是如果首字沒有大寫形式,則返回原字串。 'adi dog'.capitalize() # 'Adi dog' 'abcd 徐'.capitalize() # 'Abcd 徐' '徐 abcd'.capitalize()

C++string(字串總結

string是在C++標準模板庫中的資料型別,string型別的物件用來存放字串,且不用擔心字串越界問題,標頭檔案為<string> 1、定義string物件 string 變數名;  (1) string s1,s2;  //定義物件s1

luogu4407 [JSOI2009]電子字典 字串hash + hash

暴力列舉,然後\(hash\)表判斷 複雜度\(O(26 * 20 * n)\) 具體而言 對於操作1:暴力列舉刪除 對於操作2:暴力新增,注意新增不要重複 對於操作3:暴力替換,同樣的注意不要重複 #include <cstdio> #include <cstr

Python中非數字型變數:列表,元組,字典,字串總結

列表(儲存一組資料):list,用[]定義,資料之間用“,”分隔 定義列表: 列表名字 = [“引數1”,“引數2”……] 取值和取索引: 列表名字[索引] 索引從0開始(從前到後) 從後到前取值時:索引最後一個是-1,依次-2…… 建立一個空列表,以列表的名字加“.”,按下tab鍵,會看到

字串雜湊 模板

模板 #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int maxn=2e4+10; const int inf=0x7ffffff; inline i

C語言字串操作總結大全(超詳細) (轉)

轉自部落格園:DoubleLi 1)字串操作 strcpy(p, p1) 複製字串  strncpy(p, p1, n) 複製指定長度字串  strcat(p, p1) 附加字串  strncat(p, p1, n) 附加指定長度字串