哈希表的深入探索

定义:

其实哈希表就是我们之前在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;
        
//     }
      
// }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值