哈希算法概述

哈希用于字符串处理(快速判断两个字符串是否相同)。先介绍一下哈希的思想:

abc=97p2+98p1+99p0 a b c = 97 ∗ p 2 + 98 ∗ p 1 + 99 ∗ p 0

abd=97p2+98p1+100p0 a b d = 97 ∗ p 2 + 98 ∗ p 1 + 100 ∗ p 0

abcd=97p3+98p2+99p1+100p0 a b c d = 97 ∗ p 3 + 98 ∗ p 2 + 99 ∗ p 1 + 100 ∗ p 0

显然我们相当于把字符串变成一个p进制的数(称作这个字符串的哈希值),然后如果这个p进制的数相同就可以确定这两个字符串是相同的。但是我们发现:这个数可能会很大,所以我们只能把这两个数进行取模,限制在int范围内。但是由于取模,哈希值相同的字符串不一定相同。不过在模很大的情况下,哈希值相同,两个字符串是大概率相同的。也就是说,如果只判断两个字符串,我们只用计算两个串的哈希值然后比较是否相同,wa的几率是 1100000000 1 100000000

但是还有一类问题,我们需要判断某一个串是否出现过。有一个很直接的想法就是把所有哈希值放到bool数组中,计算一个,判断这个哈希值是否出现过。但是这个时候精度问题就十分感人。这个时候我们就需要双哈希,我们取不同的p和不同的模数,对于一个串计算两个哈希值,如果这两个同时出现过,那么也可以判断这个串出现过了。

哈希的思想是很简单的,但是写法上有技巧(令人窒息,第一次考试写wa了)。

for(int j=0;j<len;j++)  
    for(int j=0;j<len;j++)  
       hash=(hash*p+a[j])%mod;

再看一看二维哈希。

二维哈希的姿势要奇怪一点,先把p的次方填满矩阵:
这里写图片描述

然后每个格子乘上该格子的数,然后求矩阵前缀和。之后我们就可以O1查询每个矩阵的哈希值(支持加减)。虽然左上角次数不同,我们把所有次数乘成相同的就行。

有双哈希判断是否出现。

矩阵(matrix)

时间限制: 1000 ms 内存限制: 131072 KB
提交数: 33 通过数: 10

题目描述

给出一个 n×m n × m 的矩阵。让你从中发现一个最大的正方形。使得这样子的正方形在矩阵 中出现了至少两次。输出最大正方形的边长。

输入

第一行两个整数 n n ,m 代表矩阵的长和宽;
接下来 n n 行,每行 m 个字符(小写字母) ,表示矩阵。

输出

输出一个整数表示满足条件的最大正方形的边长。

输入样例

5 10
ljkfghdfas
isdfjksiye
pgljkijlgp
eyisdafdsi
lnpglkfkjl

输出样例

3

数据规模

对于 30%的数据, n,m100 n , m ≤ 100

对于 100%的数据, n,m500 n , m ≤ 500

正如上面的方法,附上代码:

#include<iostream>  
#include<cstring>  
#include<cstdio>  
using namespace std;  
struct lxy{  
    int next;  
    long long x;  
}b[250005];  

int head[100005];  
long long pr1=97,pr2=233,mod1=94271,mod2=19260819;  
int n,m,ans,cnt;  
long long p1[250005],p2[250005];  
long long hash1[505][505],hash2[505][505];  
char s[505][505];  

void add(int op,int ed)  
{  
    cnt++;  
    b[cnt].next=head[op];  
    b[cnt].x=ed;  
    head[op]=cnt;  
}  

bool check(int k)  
{  
    cnt=0;  
    memset(head,-1,sizeof(head));  
    memset(b,0,sizeof(b));  
    long long has1,has2;  
    for(int i=1;i<=n-k+1;i++)  
      for(int j=1;j<=m-k+1;j++)  
      {  
        has1=hash1[i+k-1][j+k-1]+hash1[i-1][j-1]-hash1[i-1][j+k-1]-hash1[i+k-1][j-1];  
        has2=hash2[i+k-1][j+k-1]+hash2[i-1][j-1]-hash2[i-1][j+k-1]-hash2[i+k-1][j-1];  
        has1=has1*p1[(n-i+1)*m-j]%mod1;  
        has2=has2*p2[(n-i+1)*m-j]%mod2;  
        has1%=mod1;has2%=mod2;  
        if(has1<0) has1+=mod1;  
        if(has2<0) has2+=mod2;  
        for(int p=head[has1];p!=-1;p=b[p].next)  
          if(b[p].x==has2)  
          {  
            return true;  
          }  
        add(has1,has2);  
      }  
    return false;  
}  

void er(int l,int r)  
{  
    int mid=(l+r+1)/2;  
    if(check(mid)) ans=mid;  
    if(l==r) return;  
    if(ans==mid) er(mid,r);  
    else  er(l,mid-1);  
}  

int main()  
{  
    scanf("%d%d",&n,&m);  
    long long t1=1,t2=1,ci=0;  
    for(int i=1;i<=n;i++)  
      scanf("%s",s[i]+1);  
    p1[0]=1;p2[0]=1;  
    for(int i=1;i<=n;i++)  
      for(int j=1;j<=m;j++)  
      {  
        t1=t1*pr1%mod1;t2=t2*pr2%mod2;  
        hash1[i][j]=t1;hash2[i][j]=t2;  
        p1[(i-1)*m+j]=t1;p2[(i-1)*m+j]=t2;  
      }  
    for(int i=1;i<=n;i++)  
      for(int j=1;j<=m;j++)  
      {  
        hash1[i][j]=hash1[i][j]*s[i][j]%mod1;  
        hash2[i][j]=hash2[i][j]*s[i][j]%mod2;  
      }  
    for(int i=1;i<=n;i++)  
      for(int j=1;j<=m;j++)  
      {  
        hash1[i][j]=(hash1[i][j-1]+hash1[i][j])%mod1;  
        hash2[i][j]=(hash2[i][j-1]+hash2[i][j])%mod2;  
      }  
    for(int i=1;i<=n;i++)  
      for(int j=1;j<=m;j++)  
      {  
        hash1[i][j]=(hash1[i-1][j]+hash1[i][j])%mod1;  
        hash2[i][j]=(hash2[i-1][j]+hash2[i][j])%mod2;  
      }  
    er(1,min(n,m));  
    cout<<ans;  
}  
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像检索哈希算法的发展可以追溯到20世纪70年代的早期。以下是哈希算法的发展史概述: 1. 早期哈希算法:早期哈希算法主要是基于图像的直方图特征,如颜色、纹理、形状等。这些算法在计算速度和精度方面都有所限制,因此适用范围有限。 2. 局部不变性哈希算法:2006年,Torralba等人提出了一种基于局部不变性的哈希算法,称为SIFT哈希算法。该算法使用尺度不变特征变换(SIFT)技术来提取局部特征,并使用哈希函数将这些特征映射到二进制码上。 3. 深度学习哈希算法:2014年,Wang等人提出了一种基于深度学习的哈希算法,称为DeepHash。该算法使用卷积神经网络(CNN)来提取特征,并使用哈希函数将这些特征映射到二进制码上。 4. 对抗性哈希算法:2017年,Xia等人提出了一种对抗性哈希算法,称为AHASH。该算法使用生成对抗网络(GAN)来生成对抗性样本,并使用哈希函数将这些样本映射到二进制码上。 5. 联合学习哈希算法:近年来,越来越多的研究者开始探索联合学习哈希算法。这种算法将多个任务的数据和标签联合起来,通过共享特征来提高哈希算法的精度和泛化能力。 总的来说,随着计算机视觉和深度学习技术的发展,图像检索哈希算法也在不断地演进和改进。未来,我们可以期待更加高效、准确和智能的哈希算法的出现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值