哈希表的应用可谓是十分的广泛,可以帮助我们解决很多复杂的问题。
我们可以简单地把哈希表理解为数学中的函数 y=f(x),自变量x与因变量都是唯一相互对应的。在哈希中,我们可以把x的值看作索引地址,来对y进行一系列的操作。这与我们平常定义的数据类型十分的相似。例如我们定义了一个int类型的变量y,此时电脑已经向内存申请空间了,这时再存储一个值,相应的在我们的内存中就会有对应的地址(假设为x)。现在来看哈希的原理是不是就已经清晰明了了。
当然在哈希中x并不一定是特定的类型(如单一的int、double等),我们不妨发散我们的思维,将x的值不在局限于一个单纯的数字呢?如果x是一个字符或者一个字符串是不是更方便我们解决平常遇到的一系列问题呢。
在这里我们引进c++非常实用的容器 unordered_map (当然c++还有很多不同类型的容器,例如map,set等等。在这里我们先应用unordered_map容器,值得一提的是unordered_map与map的区别在于是无序的,即存储的同时,容器不会自动进行排序功能,感兴趣的可以自作了解,这里就不过多赘述了。)
简单介绍一下unordered_map容器的用法:
头文件:#include<unordered_map>;
创建:
unordered_map<int,int> f
简单分析一下:
1、unordered_map< >表示声明创建一个unordered_map容器
2、 <int,int>我们可以把第一个int理解为自变量x,第二个int理解为因变量y或f().当然这两个int可以换成其他类型,例如<char,int>表示的就是x的取值为一个字符,y对应一个整型
3、f就是这个哈希表的名称,也可以这样理解f[x] ==> f(x)
通俗的讲就是定义了一个一元函数f(x),<a,b>规定了函数f的定义域和值域
如此我们就可以解决实际问题了。
一、查询数组中相同元素的个数:
我们通过举leetcode例题来理解:187. 重复的DNA序列 - 力扣(LeetCode)
/*一、题目描述:
给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。
二、示例
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
三、unordered_map的应用如下:*/
unordered_map<int,int> f;
for(int i=0;i<nums.size();i++)
f[nums[i]++;
//for(int i=0;i<nums.size();i++)
// f[nums[i]++;
//这里我们可以用以下代码代替
//for(int e:nums) 这里的int 我们可以用auto自动转化符来代替
// f[e]++:
//替代后的代码意思是,定义一个int类型的e来依次遍历nums数组,并将nums数组的每个元素赋值给e
二、子串匹配(字典):
同样用leetcode的例题来方便理解:187. 重复的DNA序列 - 力扣(LeetCode)
/*一、题目描述:
DNA序列 由一系列核苷酸组成,缩写为 'A', 'C', 'G' 和 'T'.。
例如,"ACGAATTCCG" 是一个 DNA序列 。
在研究 DNA 时,识别 DNA 中的重复序列非常有用。
给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。你可以按 任意顺序 返回答案。
二、示例
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC","CCCCCAAAAA"]
三、unordered_map的应用如下:*/
unordered_map<string,int>dp;
for(循环遍历){
string str=s.substr(i,L); //substr()为字符串复制函数
if(++dp[str]==2) 存储str
}
//可以了解一下c++动态数组vector迭代器