字符串hash初步(待补充进阶部分12.1)

如果key不是整数,设计散列函数:

例子题目:

如何将一个二维整点P的坐标映射为一个整数,使得整点P可以由该整数唯一地代表

假设一个整点P的坐标是(x,y),其中0<=x,y<=Range

那么可以令hash函数为H(P)=x*Range+y

这样对数据范围内的任意两个整点p1,p2,

H(p1)都不会等于H(p2)

就可以用H(P)来唯一地代表该整点P

接着可以通过证书hash的方法来进一步映射到较小的范围

字符串hash是将一个字符串S映射成一个整数,

使得该整数可以尽可能唯一地代表字符串S

先讨论(将字符串转换为唯一的整数)

 int hashFunc(char S[],int len)
  {
      int id=0;
      for(int i=0;i<len;i++)
      {
          id=id*26+(S[i]-'A');
      }
      return id;
  }

显然,如果字符串S的长度比较长,那么转换成的整数也会很大

因此注意使用时len不能太长

如果出现了小写字母

可以将A~Z作为0~25,而把a~z作为26~51

 int hashFunc(char S[],int len)
  {
      int id=0;
      for(int i=0;i<len;i++)
      {
          if(S[i]>='A'&&S[i]<='Z')
          id=id*52+(S[i]-'A');
          else if(S[i]>='a'&&S[i]<='z')
            id=id*52+(S[i]-'a')+26;
      }
      return id;
  }

而如果出现了数字,一般有两种处理方法

①按照小写字母的处理方法,增大进制至62

②如果保证在字符串的末尾是确定个数的数字

那么就可以把前面英文字母的部分按上面的思路转换成整数

再将末尾的数字直接拼接上去

例如对由三个字符加一位数字组成的字符串“BCD4”来说

就可以先将前面的“BCD”转化为整数731

然后直接拼接上末尾的4变成7314即可

int hashFunc(char S[],int len)
  {
      int id=0;
      for(int i=0;i<len;i++)
      {
          id=id*26+(S[i]-'A');
      }
          id=id*10+(S[len-1]-'0');
      return id;
  }

一个问题:

给出N个字符串(由恰好三位大写字母组成),再给出M个查询字符串

问每个查询字符串在N个字符串中出现的次数

#include<cstdio>
#define maxn 100
char S[maxn][5],temp[5];
int hashTable[26*26*26+10];
 int hashFunc(char S[],int len)
  {
      int id=0;
      for(int i=0;i<len;i++)
      {
          id=id*26+(S[i]-'A');
      }
      return id;
  }
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%s",S[i]);
        int id=hashFunc(S[i],3);
        hashTable[id]++;
    }
    for(int i=0;i<m;i++)
    {
        scanf("%s",temp);
        int id=hashFunc(temp,3);
        printf("%d\n",hashTable[id]);
    }
    return 0;
}

知识点来自于《算法笔记》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值