zoukankan      html  css  js  c++  java
  • UVA-11019 二维哈希算法

    UVA-11019

    题意:

    就是给你AB两个字符矩阵,问你B矩阵在A矩阵中的出现次数。

    题解:  参考链接:https://blog.csdn.net/qq_38891827/java/article/details/80723483

    我们可以进行二维hash,其实就是把n个横向串连在一起hash。
    注意判相等的时候,我们不断进行尺取+hash,尺取的过程,我们删除当前第一行的hash值加上最后一行的hash值,删除第一行的hash值直接删去就可以
    例如
    AAAAAA
    BBBBBB
    CCCCCC
    我们删去第一行的hash值 相当于把矩阵变成了
    000000
    BBBBBB
    CCCCCC
    此时我们再添加最后一行
    000000
    BBBBBB
    CCCCCC
    DDDDDD
    如果这时候的B矩阵是
    BBBBBB
    CCCCCC
    DDDDDD
    这两个矩阵的hash值不同的,为了处理这种情况,我们把B矩阵相应的添加前几行
    变成
    000000
    BBBBBB
    CCCCCC
    DDDDDD
    这样再去匹配就可以了。
    以上就是二维hash大概的处理方法(是我自己想的做法,如果有其他好的尺取方法欢迎指教
    掌握了这个做法,我们就可以枚举矩阵的左上角,然后对于当前列数的矩阵从上向下进行尺取,hash判断就可以了。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<sstream>
    #include<map>
    using namespace std;
    const int maxn=1e3+5;
    const int N=1e6+5;
    const int blo=31;
    typedef unsigned long long ull;
    ull hash_[maxn][maxn],xp[N];
    char str[maxn][maxn],str2[maxn][maxn];
    void init()
    {
        xp[0]=1;
        for(int i=1; i<N; ++i)
        {
            xp[i]=xp[i-1]*blo;
        }
    }
    ull Get_hash(int i,int j,int l)
    {
        return hash_[i][j]-hash_[i][j+l]*xp[l];
    }
    int main()
    {
        init();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n1,n2,m1,m2,ans=0;
            scanf("%d%d",&n1,&m1);
            for(int i=0; i<n1; ++i)
                scanf("%s",str[i]);
            scanf("%d%d",&n2,&m2);
            for(int i=0; i<n2; ++i)
                scanf("%s",str2[i]);
            for(int i=0; i<n1; ++i)
            {
                hash_[i][m1]=0;
                for(int j=m1-1; j>=0; j--)
                {
                    hash_[i][j]=hash_[i][j+1]*blo+(str[i][j]-'A'+1);
                }
            }
            ull tmp=0;
            for(int i=n2-1; i>=0; --i)
            {
                for(int j=m2-1; j>=0; j--)
                {
                    tmp=tmp*blo+(str2[i][j]-'A'+1);
                }
            }
            for(int i=0; i<m1-m2+1; ++i)
            {
                ull tmp1=tmp,tmp2=0;
                for(int j=n2-1; j>=0; j--)
                {
                    tmp2=tmp2*xp[m2]+Get_hash(j,i,m2);
                }
                if(tmp1==tmp2) ans++;
                for(int j=n2; j<n1; ++j)
                {
                    tmp2-=Get_hash(j-n2,i,m2)*xp[(j-n2)*m2];
                    tmp2+=Get_hash(j,i,m2)*xp[j*m2];
                    tmp1=tmp1*xp[m2];
                    if(tmp2==tmp1)  ans++;
                }
    
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    STL(七)之萃取技术
    STL(六)之空间配置器
    为Oracle配置监听
    Oracle11.2.01安装过程
    SVN简介
    SVN客户端安装教程
    SVN服务器安装教程
    排序算法-冒泡排序
    使用Struts2实现超级文本的链接
    排序算法-快速排序
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/13033798.html
Copyright © 2011-2022 走看看