当前位置: 首页 > 编程日记 > 正文

哈希表的分类,创建,查找 以及相关问题解决

总体的hash学习导图如下:
在这里插入图片描述

文章目录

        • 定义
        • 分类
          • 字符hash
          • 排序hash
          • 链式hash(解决hash冲突)
            • 创建链式hash
            • 查找指定数值
          • STL map(hash)
          • 哈希分类 完整测试代码
        • 应用(常见题目)
          • 1. 回文字符串(Longest Palindrome)
          • 2. 词语模式(Word Pattern)
          • 3. 同字符词语分组(Group Anagrams)

定义

  1. 需要拥有关键字 key
  2. 维护一个key和value的映射关系,哈希函数
  3. 最终的hash表拥有直接通过key访问值的能力

分类

字符hash
/*count letters*/
void hash_char() {int char_map[128] = {0};string s = "aabbbcddeh";for (int i = 0;i < s.length(); ++i) {char_map[s[i]] ++;}for (int i = 0;i < 128; ++i) {if (char_map[i] > 0) {printf("[%c] [%d]\n",i,char_map[i]);}}
}
排序hash
void hash_sort() {int arr[] = {1,100,2,6,998,532,40};int hash_arr[999] = {0};for (int i = 0;i < 7; ++i) {hash_arr[arr[i]] ++;}for (int i = 0;i < 999; i++) {if (hash_arr[i] > 0) {cout << i << endl;}}
}
链式hash(解决hash冲突)
创建链式hash
struct HashNode
{int data;struct HashNode *next;HashNode(int x):data(x),next(NULL){}
};int get_key(int key, int tabel_len) {return key % tabel_len;
}void insert_hash(HashNode *hash_table[], HashNode *node, int tabel_len) {int key = get_key(node -> data, tabel_len);node ->next = hash_table[key];hash_table[key] = node ;
}
查找指定数值
int get_key(int key, int tabel_len) {return key % tabel_len;
}bool search(HashNode *hash_table[], int value, int tabel_len) {int key = get_key(value,tabel_len);HashNode *head = hash_table[key];while(head) {if (head -> data == value) {return true;}head = head -> next;}return false;
}
STL map(hash)
void stl_hash() {std::map<string, int> map;string a[3] = {"aaa","ssss","ddd"};map[a[0]] = 1;map[a[1]] = 100;map[a[2]] = 301;cout << "stl hash_table is " << endl;for (std::map<string, int>::iterator it = map.begin(); it != map.end(); it ++) {cout << "[" << it -> first.c_str() << "] :" << it -> second << endl; }if (map.find(a[1]) != map.end()) {cout << "sss is in the stl map "  << map[a[1]]<< endl;}
}
哈希分类 完整测试代码
#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;struct HashNode
{int data;struct HashNode *next;HashNode(int x):data(x),next(NULL){}
};/*count letters*/
void hash_char() {int char_map[128] = {0};string s = "aabbbcddeh";for (int i = 0;i < s.length(); ++i) {char_map[s[i]] ++;}for (int i = 0;i < 128; ++i) {if (char_map[i] > 0) {printf("[%c] [%d]\n",i,char_map[i]);}}
}void hash_sort() {int arr[] = {1,100,2,6,998,532,40};int hash_arr[999] = {0};for (int i = 0;i < 7; ++i) {hash_arr[arr[i]] ++;}for (int i = 0;i < 999; i++) {if (hash_arr[i] > 0) {cout << i << endl;}}
}int get_key(int key, int tabel_len) {return key % tabel_len;
}void insert_hash(HashNode *hash_table[], HashNode *node, int tabel_len) {int key = get_key(node -> data, tabel_len);node ->next = hash_table[key];hash_table[key] = node ;
}bool search(HashNode *hash_table[], int value, int tabel_len) {int key = get_key(value,tabel_len);HashNode *head = hash_table[key];while(head) {if (head -> data == value) {return true;}head = head -> next;}return false;
}void stl_hash() {std::map<string, int> map;string a[3] = {"aaa","ssss","ddd"};map[a[0]] = 1;map[a[1]] = 100;map[a[2]] = 301;cout << "stl hash_table is " << endl;for (std::map<string, int>::iterator it = map.begin(); it != map.end(); it ++) {cout << "[" << it -> first.c_str() << "] :" << it -> second << endl; }if (map.find(a[1]) != map.end()) {cout << "sss is in the stl map "  << map[a[1]]<< endl;}
}int main(int argc, char const *argv[])
{cout << "hash_char" << endl;hash_char();cout << "hash_sort" << endl;hash_sort();const int TABEL_LEN = 11;HashNode *hash_table[TABEL_LEN] = {0};std::vector<HashNode *> hash_node_vec;int test[8] = {1,100,2,6,998,532,40,1};for (int i = 0;i < 8; ++i) {hash_node_vec.push_back(new HashNode(test[i]));}for (int i = 0;i < hash_node_vec.size(); ++i) {insert_hash(hash_table,hash_node_vec[i],TABEL_LEN);}cout << "hash_table" << endl;for (int i = 0;i < TABEL_LEN; ++i) {printf("[%d] ",i);HashNode *head = hash_table[i];while(head) {printf("-> %d", head->data);head = head -> next;}printf("\n");}cout << endl;for (int i =0;i < 10; ++i) {if (search(hash_table, i, TABEL_LEN)) {printf("%d is in the hash_table\n",i);} else {printf("%d is not int the hash_table\n",i);}}stl_hash();return 0;
}

输出如下:

hash_char
[a] [2]
[b] [3]
[c] [1]
[d] [2]
[e] [1]
[h] [1]
hash_sort
1
2
6
40
100
532
998
hash_table
[0] 
[1] -> 1-> 100-> 1
[2] -> 2
[3] 
[4] -> 532
[5] 
[6] -> 6
[7] -> 40
[8] -> 998
[9] 
[10] 0 is not int the hash_table
1 is in the hash_table
2 is in the hash_table
3 is not int the hash_table
4 is not int the hash_table
5 is not int the hash_table
6 is in the hash_table
7 is not int the hash_table
8 is not int the hash_table
9 is not int the hash_table
stl hash_table is 
[aaa] :1
[ddd] :301
[ssss] :100
sss is in the stl map 100

应用(常见题目)

1. 回文字符串(Longest Palindrome)

问题如下:
已知一个只包括大小写字符的 字符串,求用该字符串中的字符可以生 成的最长回文字符串长度。
例如 s = “abccccddaa”,可生成的 最长回文 字符串长度为 9,如 dccaaaccd、 adccbccda、 acdcacdca等,都是正确的。

代码实现如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;/*
已知一个只包括大小写字符的 字符串,求用该字符串中的字符可以生 成的最长回文字符串长度。
例如 s = “abccccddaa”,可生成的 最长回文 字符串长度为 9,如 dccaaaccd、 adccbccda、 acdcacdca等,都是正确的。
*/int max_count_palindrome(string s) {if (s.length() == 0) {return 0;}int hash_table[128] = {0};int max_count = 0;int flag = 0;for (int i = 0; i < s.length(); ++i) {if ((s[i] >= 'a' && s[i] <= 'z') || (s[i] >= 'A' && s[i] <= 'Z')) {hash_table[s[i]] ++;} else {return -1;}}for (int i = 0;i < 128; ++i) {if (hash_table[i] > 0 ) {if(hash_table[i] % 2 == 0) {max_count += hash_table[i];} else {max_count += hash_table[i] - 1;flag = 1;}}}return max_count + flag;
}int main(int argc, char const *argv[])
{string s;cin >> s; cout << max_count_palindrome(s) << endl;return 0;
}

输出如下:

abccccddaabb
11
2. 词语模式(Word Pattern)

问题描述如下:

已知字符串pattern与字符串str,确认str是否与pattern匹配。
str与pattern匹配代表字符 串str中的单词与pattern中的字符一一对应。(其中pattern中只包含小写字符,str中
的单词只包含小写字符,使用空格分隔。) 例如,
pattern = “abba”, str = “dog cat cat dog” 匹配.
pattern = “abba”, str = “dog cat cat fish” 不匹配.
pattern = “aaaa”, str = "dog cat cat dog"不匹配.
pattern = “abba”, str = "dog dog dog dog"不匹配.

实现如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <stdio.h>using namespace std;/*
已知字符串pattern与字符串str,确认str是否与pattern匹配。
str与pattern匹配代表字符 串str中的单词与pattern中的字符一一对应。(其中pattern中只包含小写字符,str中
的单词只包含小写字符,使用空格分隔。) 例如,
pattern = “abba”, str = “dog cat cat dog” 匹配. 
pattern = “abba”, str = “dog cat cat fish” 不匹配. 
pattern = "aaaa", str = "dog cat cat dog"不匹配. 
pattern = "abba", str = "dog dog dog dog"不匹配.
*/bool judge_word_partten(string partten, string str) {if ((partten.length() == 0 && str.length() != 0)  || (str.length() == 0)) {return false;}std::map<string, char> hash_table;int used[128] = {0};str.push_back(' ');int i = 0;int j = 0;string tmp = "";cout << partten << " " << str << endl;for(int j = 0;j < str.length(); ++j){if (str[j] == ' ') {if (hash_table.find(tmp) == hash_table.end()) {if (used[partten[i]]) {return false;}used[partten[i]] = 1;hash_table[tmp] = partten[i];} else {if (hash_table[tmp] != partten[i]) {return false;}}tmp = "";i++;} else {tmp += str[j];}}if (i != partten.length()) {return false;}return true;
}int main(int argc, char const *argv[])
{/* code */string partten = "abba";string str = "dog cat cat do";cout << judge_word_partten(partten,str) << endl;return 0;
}

输出如下:

abba 
dog cat cat do 
0abba 
dog cat cat dog 
1
3. 同字符词语分组(Group Anagrams)

问题描述:
已知一组字符串,将所有anagram(由颠倒字母顺序而构成的 字)放到一起输出。
例如:[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”] :[“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
返回:[ [“ate”, “eat”,“tea”], [“nat”,“tan”], :[ [“ate”, “eat”,“tea”], [“nat”,“tan”],[“bat”] ]

实现如下:

#include <iostream>
#include <vector> 
#include <string>
#include <map>
#include <algorithm>
#include <stdio.h>using namespace std;/*
已知一组字符串,将所有anagram(由颠倒字母顺序而构成的 字)放到一起输出。
例如:["eat", "tea", "tan", "ate", "nat", "bat"] :["eat", "tea", "tan", "ate", "nat", "bat"]
返回:[ ["ate", "eat","tea"], ["nat","tan"], :[ ["ate", "eat","tea"], ["nat","tan"],["bat"] ]
*//*map 建立 string to vector<sting> 的存储映射*/
std::vector<std::vector<string>> get_group_anagrams(std::vector<string> &str) {std::map<string, std::vector<string> > hash_table;string tmp;std::vector<std::vector<string>> result;for (int i = 0;i < str.size(); ++i){tmp = str[i];sort(tmp.begin(), tmp.end());if (hash_table.find(tmp) != hash_table.end()) {hash_table[tmp].push_back(str[i]);} else {std::vector<string> item;item.push_back(str[i]);hash_table[tmp] = item;}}std::map<string, std::vector<string> >::iterator it = hash_table.begin();for (;it != hash_table.end(); ++it) {result.push_back(it->second);}return result;
}int main(int argc, char const *argv[])
{/* code */std::vector<string> str;for (int i = 0;i < 6; ++i) {string tmp;cin >> tmp;str.push_back(tmp);}std::vector<std::vector<string> > result = get_group_anagrams(str);for (int i = 0;i < result.size(); ++i) {for (int j = 0;j < result[i].size(); ++j) {cout << "[" << result[i][j] << " ] ";}cout << endl;}return 0;
}

输出如下:

ate eat tea tan nat bat
[bat ] 
[ate ] [eat ] [tea ] 
[tan ] [nat ] 

相关文章:

android 自定义音乐圆形进度条,Android自定义View实现音频播放圆形进度条

本篇文章介绍自定义View配合属性动画来实现如下的效果实现思路如下&#xff1a;根据播放按钮的图片大小计算出圆形进度条的大小根据音频的时间长度计算出圆形进度条绘制的弧度通过Handler刷新界面来更新圆形进度条的进度具体实现过程分析&#xff1a;首先来看看自定义View中定义…

jsp error-page没有生效

1、首页检查web.xml中的配置&#xff0c;确保路径是正确的 <error-page> <error-code>404</error-code> <location>/error.jsp</location> </error-page> 2、然后再检查error.jsp文件内容是否有问题&#xff0c;比如只有<head>&…

CTO(首席技术官)

CTO&#xff08;首席技术官&#xff09;英文Chief Technology Officer&#xff0c;即企业内负责技术的最高负责人。这个名称在1980年代从美国开始时兴。起于做很多研究的大公司&#xff0c;如General Electric&#xff0c;AT&T&#xff0c;ALCOA&#xff0c;主要责任是将科…

把数组排成最小的数

题目 输入一个正整数数组&#xff0c;把数组里所有数字拼接起来排成一个数&#xff0c;打印能拼接出的所有数字中最小的一个。例如输入数组{3&#xff0c;32&#xff0c;321}&#xff0c;则打印出这三个数字能排成的最小数字为321323。 思路 一  需要找到字典序最小的哪个排列…

shell脚本自动执行,top命令无输出

shell脚本在系统启动时推后台自动执行&#xff0c;发现其中/usr/bin/top -n 1 -c -b -u ceph 命令并无输出 但是系统启动之后手动执行脚本&#xff0c;&推后台脚本中的top仍然能够正常输出&#xff0c;仅仅是系统发生重启&#xff0c;该功能就不生效了 stackoverflow 推荐…

0709 C语言常见误区----------函数指针问题

1.函数指针的定义 对于函数 void test(int a, int b){ // } 其函数指针类型是void (* ) (int , int)&#xff0c; 注意这里第一个括号不能少&#xff0c; 定义一个函数指针&#xff0c;void (* pfunc)(int , int) ,其中pfunc就是函数指针类型&#xff0c; 它指向的函数类型必须…

android 定时换图片,android 视频和图片切换并进行自动轮播

刚入android没多久&#xff0c;遇到的比较郁闷的问题就是子线程主线程的问题&#xff0c;更改UI界面&#xff0c;本想做一个图片的轮播但是比较简单&#xff0c;然后就试试实现视频跟图片切换播放进行不停的循环播放。也用过不少控件&#xff0c;但是知其然不知其所以然&#x…

Win8:Snap 实现

Win8允许分屏的操作&#xff0c;所以我们必须让我们App能对Snap模式视图做出反应&#xff0c;这样也便于通过Store的审核。如果项目中在Snap展现的功能不大&#xff0c;我们可以仅用一张logo代替&#xff0c;类似系统的商店应用。 我的项目实现效果&#xff1a; 实现思路是在你…

ping命令使用及其常用参数

PING (Packet Internet Groper)&#xff0c;因特网包探索器&#xff0c;用于测试网络连接量检查网络是否连通&#xff0c;可以很好地帮助我们分析和判定网络故障。Ping发送一个ICMP(Internet Control Messages Protocol&#xff09;即因特网信报控制协议&#xff1b;回声请求消…

g-gdb工具使用图谱(持续更新)

如下为整个GDB的学习导图

android bitmap 转drawable,android Drawable转换成Bitmap失败

错误代码&#xff1a;08-07 06:42:30.482 28497-28497/app.tianxiayou E/AndroidRuntime﹕ FATAL EXCEPTION: mainProcess: app.tianxiayou, PID: 28497java.lang.RuntimeException: Unable to start activity ComponentInfo{app.tianxiayou/app.tianxiayou.AppInfoActivity}: …

微软职位内部推荐-Software Development Engineer II

微软近期Open的职位:Job Title:Software Development EngineerIIDivision: Server & Tools Business - Commerce Platform GroupWork Location: Shanghai, ChinaAre you looking for a high impact project that involves processing of billions of dollars, hundreds of …

Lync与Exchange 2013 UM集成:Exchange 配置

有点长时间没有更新文章了&#xff0c;也是由于工作的原因确实忙不过来&#xff0c;好在博客上还有这么多朋友支持&#xff0c;非常的欣慰啊。很久没有给大家带来新东西&#xff0c;真的非常抱歉&#xff0c;今天跟大家带来的是Lync Server 2013与Exchange Server 2013统一消息…

「Java基本功」一文读懂Java内部类的用法和原理

内部类初探 一、什么是内部类&#xff1f; 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员&#xff0c;并且依附于外部类而存在的。内部类可为静态&#xff0c;可用protected和private修饰&#xff08;而外部类只能使用public和缺省的包访问权限&#…

从一致性hash到ceph crush算法演进图谱(持续更新)

参考文档&#xff1a; https://ceph.com/wp-content/uploads/2016/08/weil-crush-sc06.pdf Ceph剖析&#xff1a;数据分布之CRUSH算法与一致性Hash

[原]unity3d之http多线程异步资源下载

郑重声明&#xff1a;转载请注明出处 U_探索 本文诞生于乐元素面试过程&#xff0c;被面试官问到AssetBundle多线程异步下载时&#xff0c;愣了半天&#xff0c;同样也被深深的鄙视一回&#xff08;做了3年多u3d 这个都没用过&#xff09;&#xff0c;所以发誓要实现出来填补一…

android首页图片轮播效果,Android_Android自动播放Banner图片轮播效果,先看一下效果图支持本地图 - phpStudy...

Android自动播放Banner图片轮播效果先看一下效果图支持本地图片以及网络图片or本地网络混合。使用方式&#xff1a;android:id"id/banner"android:layout_width"match_parent"android:layout_height"230dip">核心代码&#xff1a;int length …

mongodb 入门

在NOSQL的多个数据库版本中,mongodb相对比较成熟,把学mongodb笔记整理在这&#xff0c;方便以后回顾。这笔记预计分三部分&#xff1a; 一&#xff0c;基础操作&#xff0c;二、增删改查详细操作&#xff0c;三、高级应用。一、在linux在安装mongodb&#xff0c;在linux下安装m…

springboot 学习笔记(三)

&#xff08;三&#xff09;用jar包启动springboot项目 1、首先需要在pom文件中添加依赖&#xff0c;spring-boot-starter-parent包含有打包的默认配置&#xff0c;如果要修改的话要可以进行重新定义&#xff0c;具体内容参考https://docs.spring.io/spring-boot/docs/2.1.1.RE…

搜索:深搜/广搜 获取岛屿数量

题目描述&#xff1a; 用一个二维数组代表一张地图&#xff0c;这张地图由字符“0”与字符“1”组 成&#xff0c;其中“0”字符代表水域&#xff0c;“1”字符代表小岛土地&#xff0c;小岛“1”被 水“0”所包围&#xff0c;当小岛土地“1”在水平和垂直方向相连接时&#xf…

2.4.4.1、Django新建APP(acounts)

$django-admin.py startapp accounts 在oss/accounts修改forms.py(新建)和views.py如下&#xff1a; 注&#xff1a;绿字部分为注释 views.py ################################################################ #codingutf-8 from django.core.urlresolvers import reverse f…

vue html引入资源dev下404,webpack vue 项目打包生成的文件,资源文件报404问题的修复方法(总结篇)...

最近在使用webpack vue做个人娱乐项目时&#xff0c;发现npm run build后&#xff0c;css js img静态资源文件均找不到路径&#xff0c;报404错误。。。网上查找了一堆解决办法&#xff0c;总结如下一、首先修改config目录下的index.js文件将其中build的配置项assetsPublicPat…

解决.net webservice的WebClient或HttpWebRequest首次连接缓慢问题

【编程环境】Visual Studio 2010, NET4.0 【开发语言】C#, 理论上VB.NET等依赖.NET Framework框架的语言均受此影响 【问题描述】 使用HttpWebRequest抓取网页内容,但首次请求总是莫名奇妙的阻塞在Request.GetResponse();上,不过一旦这次请求成功&#xff0c;后续的操作就很快了…

2019-1-11

unique的使用&#xff1a; 1. unique是把相邻的重复元素放到最后面。所以在对无序数列使用之前&#xff0c;需要用sort先排序。 2.unique的返回值是不重复区的的最后一个元素加一的地址。 sort(V.begin(), V.end() ); vector<int>::iterator end_unique unique&#xff…

搜索:广搜 词语阶梯

问题描述以及解决过程如下导图 广搜实现如下 #include <iostream> #include <algorithm> #include <vector> #include <string> #include <queue> #include <set> #include <map>using namespace std;/*判断两个单词是否有连接状态…

float属性html,详解CSS样式中的float属性

详解CSS样式中的float属性。float是 css样式的定位属性。我们在印刷排版中&#xff0c;文本可以按照需要围绕图片。一般把这种方式称为“文本环绕”。在网页设计中&#xff0c;应用了CSS的float属性的页面元素就像在印刷布局里面的被文字包围的图片一样。浮动的元素仍然是网页流…

机房收费系统系列一:运行时错误‘-2147217843(80040e4d)’;用户‘sa’登陆失败...

做机房收费系统的时候&#xff0c;首先在SQL server数据库中添加好charge数据库&#xff08;在对象资源管理器中&#xff0c;右击数据库&#xff0c;点击附加&#xff0c;找到charge的mdf文件&#xff0c;点击确定&#xff09;&#xff0c;然后用ODBC配置好数据库&#xff0c;把…

JQuery新浪1630个表情插件

1.http://***/Detail.aspx?id131 2.http://***/Detail.aspx?id81转载于:https://www.cnblogs.com/zrp2013/archive/2013/05/17/3082961.html

linux open系统调用的O_DIRECT标记

前言 open系统调用中针对打开的文件描述符&#xff0c;可以增加一个O_DIRECT标记&#xff0c;该标记能够使得针对该文件描述符的写操作绕过操作系统page cache&#xff0c;直接进入通用块设备层&#xff0c;从而减少页缓存对IO效率的影响。 但是针对O_DIRECT标记有一个问题&a…

计算机专业每年都有国企招老吗,这十大专业在国企中最受欢迎,待遇高、前景好,有你的专业吗?...

古语说“三百六十行&#xff0c;行行出状元”这句话一点没错&#xff0c;但是当你报考传说中的“铁饭碗”、“金饭碗”的时候&#xff0c;你会发现&#xff0c;想入对行&#xff0c;首先你得选对专业&#xff0c;不管是对于报考还是以后的职业发展来说&#xff0c;选对专业和嫁…