0
点赞
收藏
分享

微信扫一扫

字符串Hash

大漠雪关山月 2022-03-26 阅读 49

思路:

1)将字符串转化为p(经验值为131 || 13331 )进制的数 再模Q (一般取值为2^63)
2)将字符串拆分为前缀子串进行hash 计算
eg: 字符串为“ABCDE” , array : h[] 为字符串的前缀字串数组
"A":	 h[1] =  Ascii(A) % Q; //  (A)
"AB"	 h[2] =  (Ascii(A)*p + Ascii(B))%Q; // (A*p + B)
"ABC"	 h[3] =  (Ascii(A)*p^2 + Ascii(B) * p   + Ascii(C) ) %Q; // (A*p^2 + B*p + C)
...
3)查询字符串[l,r];

在这里插入图片描述

由前面 的字符串前缀到 l 的hash值为h[l]

由前面 的字符串前缀到 r 的hash值为h[r]

可以得出 区间[l,r] 的字符串哈希值为:
h [ l , r ] = h [ r ] − h [ l − 1 ] ∗ p r − l + 1 h[l,r] = h[r] -h[l-1]*p^r-l+1 h[l,r]=h[r]h[l1]prl+1

题目:AcWing 841

在这里插入图片描述

import java.util.*;
public class Main{
    static int p = 131 ; //  13331
    static int N = (int) 1e5+5;
    static long[] h = new long[N];
    static  long[] po = new long[N];
    public static void main(String[] args ){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        String s = sc.next();
        po[0] = 1;
        for(int i = 1 ; i <= n ; i ++){
            h[i] = h[i-1]*p +s.charAt(i-1);   //  设置前缀字符数组
            po[i] = po[i-1]*p;  //  设置位移权值

        }
        for(int i = 0 ; i < m ; i++){
            int l1 = sc.nextInt();
            int r1 = sc.nextInt();
            int l2 = sc.nextInt();
            int r2 = sc.nextInt();
            long s1 = h[r1] - h[l1-1] * po[r1-l1+1];   //  计算hash值
            long s2 = h[r2] - h[l2-1] * po[r2-l2+1];
            if(s1 == s2 )   System.out.println("Yes");
            else System.out.println("No");
        }
    }
}
举报

相关推荐

0 条评论