定义:
其实哈希表就是我们之前在c语言是用另一个数组去存放该数组每个元素出现的次数的扩展,
Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
意义:
为什么要在其他语言中加入这种数据结构,因为在c语言中你得考虑存放数组的范围的区间范围,来考虑你需要开辟的数组的空间,当时数组这种也有局限性,首先会造成空间浪费,而后如果需要存放的数组中有负数,造成成了一定难度,以为数组的下标是从0开始的,而不是从负数开始的
所以在其他语言就出现了专门的数据结构
结构:
1:数组
2:集合
3:映射
以c++为例:
以java为例:
例题:
1.CCF--重复局面
思路:
就是给你一个一个字符串,让你看到该字符串出现的他前面出现的次数,包括他自己
代码:
#include<iostream>
#include<unordered_map>
using namespace std;
int main(){
unordered_map<string,int>hash;
int i,j;
int n;
cin>>n;
string s1;
for(i=0;i<n;i++){
string s="";
for(j=0;j<8;j++){
cin>>s1;
s+=s1;
}
hash[s1]++;
cout<<hash[s1]<<endl;
}
}
2.leetcode--187重复的DNA序列
思路:
题目的意思在给了的字符串内依次截取长度为10的子字符串,所以我们只需要两个for循环解决,最后再用unordered_map的数据结构储存一下所有的子字符串就行,并且满足条件,就存放到vector就行
代码:
class Solution {
public:
vector<string> findRepeatedDnaSequences(string s) {
int i;
vector<string>ans;
unordered_map<string,int>hash;
int len=s.length();
for(i=0;i<=len-10;i++){
string s1="";
for(int j=i;j<10+i;j++){
s1+=s[j];
}
if(++hash[s1]==2){
ans.push_back(s1);
}
}
return ans;
}
};
3.leetcode--3无重复的最长子串
dai
代码如下:与前两题一样,需要要有移动的思想
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int i,j;
int n=s.length();
int maxlen=0;
string s2;
for(i=0;i<n;i++){
string s1="";
for(j=i;j<n;j++){
if(s1.find(s[j])!=-1) break;
else s1+=s[j];
}
int b=s1.length();
maxlen=max(maxlen,b);
}
return maxlen;
}
4.leetcode--2586统计范围内的原因字符串数
思路:枚举+哈希
第一种去调用函数判断,设定一个布尔类型的函数去判断,每次满足条件就,结果加一
代码如下:
bool panduan(string s){
int n=s.length();
if((s[0]=='a' ||s[0]=='e' || s[0]=='i' ||s[0]=='o' ||s[0]=='u')&&(s[n-1]=='a' ||s[n-1]=='e' || s[n-1]=='i' ||s[n-1]=='o' ||s[n-1]=='u')) return true;
else return false;
}
class Solution {
public:
int vowelStrings(vector<string>& words, int left, int right) {
int i;
int count=0;
for(i=left;i<=right;i++){
if(panduan(words[i])) count++;
}
return count;
}
};
第二种方法:
哈希集合去实现
代码如下:
class Solution {
public:
int vowelStrings(vector<string>& words, int left, int right) {
unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};
int ans = 0;
for (int i = left; i <= right; ++i) {
const string& word = words[i];
if (vowels.count(word[0]) && vowels.count(word.back())) {
++ans;
}
}
return ans;
}
};
5.多比特杯武汉工程大学第六届ACM新生赛-C谁能留下呢
思路 :
看到第二张图片的时候,就觉的应该用map,但是用map最后面会有一个排序问题
并且本题给出的同分的人,排名还相同,所以可以在map之外开辟一个数组,直接用这个数组去存放值,并且让他从大到小排列,最后卡他的下标值就行,少了工作量,
我见其他代码,使用链表去储存变量,之后再存到map也行。
代码如下:
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp0(int a,int b){
return a>b
;}
bool cmp(const pair<string,int>a,pair<string,int>b){
return a.second>b.second;
}
int main(){
int n;
cin>>n;//对值排序
int i,j;
string s;
int p;
map<string,int>hash;
int arr[n];
for(i=0;i<n;i++){
cin>>s>>p;
arr[i]=p;
hash[s]=p;
}
sort(arr,arr+n,cmp0);
int o=n*3/10;
string target;
int q;
int u=arr[o-1];
cin>>q;
while(q--){
cin>>target;
if(hash[target]>=u) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}}
// // vector<pair<string,int>>v(hash.begin(),hash.end());
// // sort(v.begin(),v.end(),cmp);
// int q;
// cin>>q;
// string target;
// int o=n*3/10;
// int arr[n];
// for(i=0;)
// for(i=0;i<q;i++){
// cin>>target;
// }
// }