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\n",ans);
    }
    return 0;
}

 

posted @ 2020-06-02 21:20  kongbursi  阅读(282)  评论(0编辑  收藏  举报