首页 > 其他分享 >Hash

Hash

时间:2024-05-08 11:46:13浏览次数:14  
标签:Hash 函数 质数 long 字符串 quad

Hash思想及原理

\(\quad Hash\)的思想与离散化有些许类似,都是把一个较大的域映射到一个较小的、方便比较的域中,以达到降低时间复杂度的目的。

\(\quad Hash\)的精髓在于\(Hash\)函数。它并不是一个确定的函数,而是要求各位\(Oier\)自己定义,(怎么定义?想怎么定义就怎么定义)。当处理数据时,你就可以通过\(Hash\)函数将得到的数据转化为一个数据大小合适的值,并将其映射在一个相对较小的表里,在查询时,就可以直接通过\(Hash\)值来定位数据。

\(\quad\) 这里举个简单的例子:
在处理" \(yhk\) "这个字符串时,我们可以将这三个字符的\(ASCII\)码加起来,得到的 "\(333\)"即可代表"\(yhl\)" 。 “字符串各位的\(ASCII\)码之和” 就是这个例子中的\(Hash\)函数

Hash冲突

\(\quad\)简单理解就是两个不同的数据,在经过某个\(Hash\)函数处理后,映射到了一个位置(也就是\(Hash\)函数值相等)。此时,这两个不同的数据将无法区分。

\(\quad\)可以拿上面的\(Hash\)函数举例,将字符串的各位的\(ASCII\)码相加这个\(Hash\)函数,显然,它无法处理字符出现顺序不同的字符串。
\(\quad\)也就是说,只要两个字符串含有的对应字符及数量均相同,就会被认定为是同一个字符串。
\(\quad\)所以,我们可以想一个更好用的\(Hash\)函数,来防止这种问题。

常用的\(Hash\)函数

\(\quad\)对于一个字符串,我们可以将他看作是一个\(base\)进制的数字,这样就可以保证两个字符串的\(Hash\)值不相等了。但是这又会引出另一个问题,对于一个较长的字符串,它的\(Hash\)值可能会很大,超出了我们可以接受的范围,所以我们就可以指定一个模数p,让每个\(Hash\)值都模上这个模数,这样所有字符串的\(Hash\)值就不会大于你指定的模数了。

\(\quad\)这种处理方法,缩小了\(Hash\)函数的值域,但是就会让\(Hash\)冲突的问题死灰复燃。只要两个字符串的\(Hash\)函数值在模p(先前指定的模数)意义下同余,就会被认为是一个字符串。所以我们在处理时要让p在合理的范围内尽量大一些,减小\(Hash\)冲突的概率。

\(\quad\)当然你也可以用一些更加四人的\(Hash\)函数,比如给每一位一个特定的质数,再给每个字符一个特定的质数,在算\(Hash\)函数时,求每一位字符对应质数与位数对应质数之积的积。这样还要筛质数,要么就自己背下来几个质数(doge),所以建议不要使用。

你已经通过过了新手教程,接下来开始冒险吧。

\(\qquad \qquad \qquad\) 按任意键以开始游戏(doge)


\(\quad\)就是找出一个字符串中某个字符串出现的次数,把两个字符串的\(Hash\)值都算出来,用h数组记录到第i位时较长字符串的\(Hash\)值,直接暴力枚举起点比较即可。

点击查看代码
    #include<bits/stdc++.h>
    using namespace std;
    const int p=19260817,b=233,N=1e6+10;
    int n,m;
    long long h[N],op[N];
    string s,sl;
    void Hash(string s){
    	long long ans=0;
    	for(int i=0;i<s.length();i++){
    		ans=(ans*b+s[i])%p;
    		h[i]=ans;
    	}
    }
    int get_hash(int l,int r){
    	return (h[r]-1ll*(l>=1?h[l-1]:0)*op[r-l+1]%p+p)%p;
    }
    long long get_Hash(string s){
    	long long ans=0;
    	for(int i=0;i<(int)s.length();i++)ans=((long long)ans*b+s[i])%p;
    	return ans;
    }
    string r(){//安利一手我的字符串快读,具体数值要根据题目调整。
    	char ch=getchar();string ans;
    	while(!(ch>=97&&ch<=122)&&!(ch>=65&&ch<=90))ch=getchar();
    	while((ch>=97&&ch<=122)||(ch>=65&&ch<=90))ans+=ch,ch=getchar();
    	return ans;
    }
    int main(){
    	scanf("%d",&m);
    	op[0]=1;
    	for(int i=1;i<N;i++)op[i]=op[i-1]*b%p;
    	while(m--){
    		s=r(),sl=r();
    		int l=s.length(),len=sl.length();
    		int o=get_Hash(s),ans=0;
    		Hash(sl);
    		for(int i=0;i<=len-l;i++){
    			if(get_hash(i,i+l-1)==o)ans++;
    		}
    		printf("%d\n",ans);
    	}
    }

标签:Hash,函数,质数,long,字符串,quad
From: https://www.cnblogs.com/0shadow0/p/18179350

相关文章

  • HashCode 为什么使用 31 作为乘数?
    为什么java的hashcode的选用31次方?以下是java源码部分publicinthashCode(){inth=hash;if(h==0&&value.length>0){charval[]=value;for(inti=0;i<value.length;i++){h=31*h+val[i];......
  • 高一下三调|ssy的队列|hash dp|题解
    SSY的队列题目链接解析:考场上看到这个题第一眼是绝望的,毕竟数论咱是一窍不通.但是往下细看了看这个数据范围,N是很小的,就想了想模拟.然而只骗到10分.这个题绩效较高的解法是状压dp,在N<15的范围之内均可薄纱(ppllxx_9G也是成功拿到这70rank1了orz),可得70,但是一到后......
  • 字符串基础(hash,KMP,AC自动机,trie)
    trie树trie树,又叫字典树,就是把字符串的每个字母看做树上的一个节点,若干个字符串组成了一棵trie树。最一般的trie树好像只能搜索字符串,重点是01trie和可持久化trie树和用trie树来建ac自动机(详见AC自动机)。这里着重介绍一下01trie01trie,就是节点代表了数上的二进制位上的数。......
  • windows密码存储以及hashdump所得信息解析
    1.windows登录的明文密码,存储过程是怎么样的,密文存在哪个文件下,该文件是否可以打开,并且查看到密文在Windows中密码通常不会以明文形式存储。系统会通过保存密码的哈希值来确保安全性。这个过程涉及到NTLM或Kerberos身份认证协议,它们负责加密存储密码。以下是存储过程的简要说......
  • Hashtable和ConcurrentHashMap如何实现线程安全
    感谢一起重温此知识点的同学--糖糖HashMap线程不安全,效率高put方法没有锁//任意地方声明HashMap,点击put即可进入源码HashMap<String,String>hashMap=newHashMap();hashMap.put("heart","糖糖");//HashMap.put(key,value)部分源码publicVput(Kkey,Vvalue){......
  • hash hash hash : ))
    hash:hash简述,大概就是把一个字符串映射到一个整数上(这个整数就是一个自定义进制(mode)的数),通过比较该整数匹配字符串,这样可以实现字符串之间的O(1)匹配.为什么要按位处理,因为这样方便分离字串.怎么映射?就是将每位(i)分离乘上\(mode^{(i-1)}\),得到的映射整型就是这个字......
  • 通配符匹配|dfs,hash|题解
    [CQOI2014]通配符匹配题目描述几乎所有操作系统的命令行界面(CLI)中都支持文件名的通配符匹配以方便用户。最常见的通配符有两个,一个是星号(*),可以匹配0个及以上的任意字符:另一个是问号(?),可以匹配恰好一个任意字符。现在需要你编写一个程序,对于给定的文件名列表和一个包含通配符的......
  • JDK源码分析-HashSet
    概述HashSet是Java集合框架中非常重要的一个类,它实现了Set接口,不允许出现重复元素,并且元素是无序的。HashSet的底层实现主要依赖于HashMap,通过HashMap来存储元素。如果想要了解HashMap,可以查看后续文章。类图从以上类图可以看到,HashSet实现了三个接口,继承了一个抽象类:Serial......
  • springboot~redis的hash结构为key设置过期策略
    redis配置文件开启键过期#The"notify-keyspace-events"takesasargumentastringthatiscomposed#ofzeroormultiplecharacters.Theemptystringmeansthatnotifications#aredisabled.##Example:toenablelistandgenericevents,fromthepo......
  • HASHCTF2024
    SecretofKeyboard签到脚本题,有些同学的脚本解出来大小写不正确可能是由于脚本无法识别shift+字母的组合键首先使用tshark:tshark-rusb.pcap-Tfields-eusb.capdata|sed'/^\s*$/d'>usbdata.txt提取数据并删除空格然后脚本一把梭出来:keyboard.py:normalKeys={......