字符串哈希表的一个实现

Hash(哈希(字符串哈希))模板和做题总结(详细易懂) 文章目录 系列文章目 前言 一、pandas是什么? 二、使用步骤 1.引入库 2.读入数据 总结 一 拉链法处理hash冲突模板 开放寻址法指的是当你发现这个位置已经被占用后,就按照一定的喜好去寻找没有被占用的位置。寻找 新的位置的方法 #include <cstring> #include <iostream> using namespace std; const int N = 1e5 + 3; // 取大于1e... 阅读详情

http://hi.baidu.com/%C2%F8%CD%B7%CA%C7%B0%FC%D7%D3/blog/item/e14e59d6105c552307088b92.html

 

 

怎么快速查找我要的资料呢

Description
招生考试,初试结束后,校方会贴出一张大榜单,上面是通过初试获得复试资格的考生名单。考生和家长一大早都来看榜,但是一面墙那么大的名单,要看很久才能看完。怎么能快一些呢?一般来说,名单按姓氏笔画或拼音字母排序,是一张有序表,这就让我们想到了基于有序表的二分查找算法 binarysearch, 而我们学计算机的知道还有一种叫做 哈希 的方法 hash。

这个问题就是要求 Acmer 实现在名单中快速查找某一姓名的算法。



Input
输入数据分为名单和询问两部分。

首先是名单部分,第一行是一个正整数 n (n<=500000), 表示名单中的人数。下面 n 行, 每一行有一个由大写字母A-Z和小写字母a-z组成的字符串,代表名单中的姓名。

然后是询问部分,第一行是一个正整数 m (m<=10000), 表示询问的次数。下面 m 行, 每一行有一个由大写字母A-Z和小写字母a-z组成的字符串,代表要查询的姓名。


输入中的每个字符串长度不超过10。


Output
对于每一次查询,如果要查询的字符串出现在名单中输出 "YES", 否则输出 "NO"。(注意不要加引号)
每一次查询占一行。


Sample Input

5
abc
edfg
x
a
Mike
3
Mike
bc
EDFG


Sample Output

YES
NO
NO



Hint
二分查找,hash 只是作为提示,并不要求一定要用它们来解题。

如果使用 map, set 等等, 很有可能超时,对于 Java 也是如此。

建议使用 scanf(), printf(), 有助于提高效率,对于 Java 任选输入方式。

注意,区分大小写,而且可能有相同的名字。

----------------------------------------------------------------------------------------------------------------------------------

    上面是BOJ的1003题,最简单的方法是调用C下库函数 qsort 和 bsearch (stdlib.h),即首先对所有字符串快速排序,然后二分查找。提交后,Memory:6616K   Time:831MS。这么写很逆天。

    但既然题目点到了hash,对咱种初学者来说最好还是动动手实现下比较好。下面就贴出用哈希表解决这道题的代码:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#define HashTableSize 650000

typedef struct Node HashNode;

struct Node {
            char * str;
            HashNode * next;
      };

//ELF Hash Function
unsigned int ELFHash(const char * str)
{
      unsigned int hash = 0;
      unsigned int x = 0;

      while (*str) {
                  hash = (hash << 4) + (*str++);

                  if ((x = hash & 0xF0000000L ) != 0) {
                              hash ^= ( x >> 24);
                              hash &= ~x;
                        }
            }

      return hash&0x7FFFFFFF;
}

void HashInsert(char * str, HashNode ** HashTable)
{
      int key;
      HashNode * tempA, * tempB;
      key = ELFHash(str) % HashTableSize;

      if (HashTable[key] == NULL) {
                  HashTable[key] = (HashNode *)malloc(sizeof(HashNode));
                  HashTable[key]->str = str;
                  HashTable[key]->next = NULL;
                  return;
            }

      tempA = HashTable[key];

      while (tempA != NULL) {
                  if (!strcmp(tempA->str, str)) return;

                  tempB = tempA;

                  tempA = tempA->next;
            }

      tempA = (HashNode *)malloc(sizeof(HashNode));

      tempA->str = str;
      tempA->next = NULL;
      tempB->next = tempA;

      return;

}

HashNode*  HashSearch(const char * str, HashNode ** HashTable)
{
      int key = ELFHash(str) % HashTableSize;
      HashNode * temp;

      if (HashTable == NULL || HashTable[key] == NULL) return NULL;

      temp = HashTable[key];

      while (temp != NULL) {
                  if (!strcmp(temp->str, str)) return temp;

                  temp = temp->next;
            }

      return NULL;

}

int  HashDelete(char * str, HashNode ** HashTable)
{
      HashNode * tempA, *tempB = NULL;
      int key = ELFHash(str) % HashTableSize;

      if (HashTable == NULL) return 0;

      tempA = HashTable[key];

      if (strcmp(tempA->str, str) == 0) {
                  HashTable[key] = tempA->next;
                  free(tempA);
                  return 1;
            }

      tempB = tempA->next;

      while (tempB->next) {
                  if (strcmp(tempB->str, str) == 0) {
                              tempA->next = tempB->next;
                              free(tempB);
                              return 1;
                        }

                  tempA = tempA->next;

            }

      return 0;
}

void HashDestory(HashNode *** HashTable)
{
      int i;
      HashNode * temp;

      for (i = 0;i < HashTableSize;i++) {
                  while ((*HashTable)[i] != NULL) {
                              temp = (*HashTable)[i];
                              (*HashTable)[i] = (*HashTable)[i]->next;
                              free(temp);
                        }
            }

      free(*HashTable);

      *HashTable = NULL;
}

HashNode ** HashInit(int size)
{
      HashNode ** HashTable = (HashNode **)calloc(size, sizeof(HashNode *));
      return HashTable;
}

void HashDisplay(HashNode ** HashTable)
{
      int i;
      HashNode * temp;

      if (HashTable) {
                  for (i = 0;i < HashTableSize;i++) {
                              printf("%d: ", i);
                              temp = HashTable[i];

                              while (temp) {
                                          printf("%s", temp->str);

                                          if (temp = temp->next) printf("-->");
                                    }

                              printf("/n");
                        }
            }

}

void main()
{
      char str[500000][11];
      char cmp[11];
      HashNode ** HashTable = NULL;
      int m, n, i;

      HashTable = HashInit(HashTableSize);
      scanf("%d", &n);

      for (i = 0;i < n;i++) {
                  scanf("%s", str[i]);
                  HashInsert(str[i], HashTable);
            }

      scanf("%d", &m);

      for (i = 0;i < m;i++) {
                  scanf("%s", cmp);

                  if (HashSearch(cmp, HashTable))
                        printf("YES/n");
                  else
                        printf("NO/n");
            }

      HashDestory(&HashTable);

}
提交后:Memory:9612K     Time:375MS
采用的是链地址法处理冲突,散列函数为ELFHash。
Hash表属于空间换时间的一种方法,明显可以看到时间减少了一半多。不过上面的程序空间上应该还可以再优化。
字符串求每一个字符出现的次数-哈希表方式实现-C描述 //求字符串出现字符次数,求第一个次数为一的值 //哈希->哈希表概念 /* 建立一个HashTable进行映射 ①HashTable的下标作为charTable 映射Key ,数组元素作为 Value */ #include #include #include //求字符串出现字符次数,求第一个次数为一的值 //哈希->哈希表概念 /* 建立一个HashTable进行映射 阅读详情

相关推荐

算法导论---------------散列表(hash table)

摘要:   本章介绍了散列表(hash table)的概念、散列函数的设计及散列冲突的处理。散列表类似与字典的目录,查找的元素都有一个key与之对应,在实践当中,散列技术的效率是很高的,合理的设计散函数和冲突处理方法,可以使得在散列表中查找一个元素的期望时间为O(1)。散列表是普通数组概念的推广,在散列表中,不是直接把关键字用作数组下标,而是根据关键字通过散列函数计算出来的。书中介绍散列表非

chen 1581

哈希表的详细介绍及其实现~

哈希表的详细介绍及其实现~

qq_57603004的博客 1613

编程珠玑: 15.1实现一个哈希表统计字符串出现次数 -------解题总结

#include #include #include #include using namespace std; /* 问题:统计书中的单词及出现次数,实现一个数据结构进行存储 分析:典型的信息检索中的倒排索引问题。可以采用链表数组实现: 哈希 + 拉链法 一种做法是:根据给定的单词个数n,选取最接近n的质数k,然后对字符串进行散列, h = 31 * h + char

qingyuanluofeng的专栏 1535

c语言实现哈希表

哈希表

tjh1998的博客 8144

C++ 利用哈希表对字符串进行处理

定义一个函数,输入两个字符串,从第一个字符串中删除第二个字符串重复的字符 #include <iostream> #include <map> using namespace std; string delete_duplicate_char(string str,const string str1) { if(str1.empty()) ret...

小鸟在飞想的专栏 1385

哈希表例子(C语言实现)

/* * 题目:给定一个全部由字符串组成的字典,字符串全部由大写字母构成。其中为每个字符串编写密码,编写的 * 方式是对于 n 位字符串,给定一个 n 位数,大写字母与数字的对应方式按照电话键盘的方式: * 2: A,B,C 5: J,K,L 8: T,U,V * 3: D,E,F 6: M,N,O 9: W,X,Y,

IceTea的专栏 3579

【C++进阶】哈希表的实现

哈希表的实现

m0_67077469的博客 1031

哈希表课程设计

设计散列表实现手机号码查找系统,对手机号码进行Hash。 [基本要求] (1) 设每个记录有下列数据项:手机号码、姓名、性别、E-mail地址。 (2) 从文件读入各记录,以手机号码为关键字建立散列表(长度为43)。采用开放定址法建立散列表。 (3)显示开放定址散列表最高的寻址次数,若次数过高,则重建散列表; (4)输入手机号码,对该手机号码进行哈希查找,显示散列的次数,若号码存在,则显示号码对应的人名、性别以及邮件地址,否则提示该号码不存在

数据结构-哈希-哈希表实现

🚀当插入的某组数据中存在局部集中一些数据时,哈希冲突是很严重的,一个数据占据了另一个数据的位置,另一个位置就要去占据一个其他数据的位置,这样一些数据较为集中的时候,哈希冲突是很严重的导致效率较低。🚀下面实现这开散列的形式是更为优秀的,其哈希冲突的概率于闭散列相比是更低的。🚀应用开散列,对于每个结点要增设链接的指针,似乎增加了空间的开销。

Djsnxbjans的博客 1818

自己实现的字符串hash类

自己用MFC和STL实现的字符串HASH存储方案,适合在MFC环境下用,也可以拿去学习,体会实现思路,掌握HASH快速访问原理,了解一下

基于单片机控制的开关电源设计

采用开关电源技术和MCU模块,凭借可靠性高、易于调适的特点,可以更高效地发挥出二者的优势,从而实现更好的组合。stm32的起动模式是通过Boot0和Boot1两个管脚的高低电平来决定的,当stm32被供电之后,这两个管脚的电平。在 VCC上,键盘的一头(列线)被连接到 VCC上,而在“0”的编程输出中,则用来进。,在开关管打开的情况下,由输入电力供给电流,感应装置存储   Buck变换器是一种非隔离式的电压转换器[10]整流电路对输入电压进行整流,再经过滤波电路,即Dc电压是直流/直流变换器的直流输入。

QQ1694456187的博客 2308

[ASCII,散列函数,哈希表,字符串,Hash函数]「译」C语言实现一个简易的Hash table

  我们会讲解Hash函数和实现算法,并手动实现一个Hash函数。   Hash函数   本教程中我们实现的Hash函数将会实现如下操作:   输入一个字符串,然后返回一个0到m(Hash表的大小)的数字为一组平常的输入返回均匀的bucket索引。如果Hash函数不是均匀分布的,就会将多个记录插入到相同的bucket中,这就回提高冲突的几率,而这个冲突就会影响到我们的Hash表的效率。   Hash算法   我们将会设计一个普通的字符串Hash函数,在伪代码中表示如下:   function..

iqifenxia的博客 390

告别复杂配置!5分钟在Vue/React项目中集成讯飞语音听写WebSocket API

本文详细介绍了如何在Vue/React项目中快速集成讯飞语音听写WebSocket API,实现高效语音识别功能。通过对比不同通信方案,突出WebSocket在实时语音交互中的优势,并提供框架适配、音频处理及性能优化等关键技术点,帮助开发者5分钟内完成专业级语音听写功能集成。

weixin_28730353的博客 274

哈希表对字符串的高效处理3:实现一个听高级的字符匹配算法

举一反三: 功能:实现一个听高级的字符匹配算法 测试数据1:123 1*2**3***  样例输出:匹配成功 测试数据2: 123 1**3*****2 样例输出:匹配成功 测试数据3: 123 1**2****** 样例输出:匹配不成功 //思路:创建创建一个长度为256的数组,每个字母根据其ASCII码值作为数组的下标对应数组的对应项,而数组中存储的0、1对应每个字符是否出现。这样我

Voidwalkerxiaohui 1115

麒麟桌面操作系统QT开发环境搭建

麒麟操作系统安装Qt

因为热爱,所以坚持,记录工作中的乐趣 9275

别再死记硬背公式了!用ADS手把手教你仿真一个4GHz镜像抑制混频器(附完整工程文件)

本文详细介绍了使用Keysight ADS软件设计和仿真4GHz镜像抑制混频器的完整流程。从理论分析到实际工程实现,涵盖分支线耦合器设计、二极管建模、噪声系数仿真及性能优化等关键步骤,帮助工程师摆脱公式死记硬背,掌握实用的射频电路设计技能。附完整工程文件,可直接应用于实际项目开发。

weixin_28683391的博客 496

散列表(哈希表)

转自         该篇分别讲了散列表的引出、散列函数的设计、处理冲突的方法。并给出一段简单的示例代码。 2、散列表的引出         给定一个关键字集合U={0,1......m-1},总共有不大于m个元素。如果m不是很大,我们可以定义一个数组T[0...(m-1)],把U映射到数组T上,每个位置对应U中的一个关键字,若U中没有关键字为k的元素,则T[k]=NULL。

super_marioli的专栏 1180

Android 14 (AOSP) 源码架构深度解析与开发者指南

Android14源码的仓库指南信息

保持专注,保持热爱 1186

哈希表(Hash)

哈希表是一种基于哈希函数建立的一种查找表,也叫作散列表,是根据关键字和值直接进行访问的数据结构,其关键思想是使用哈希函数,将键key和值value映射到对应表的某个区块中。在哈希表的实际应用中,关键字的类型除了数字类型,还有可能是字符串型、浮点数、大整数型,甚至还有可能是集中类型的组合。

monlyy的博客 1056

黑猫带你学eMMC协议第22篇:emmc可靠写详解(Write Reliability)

1 前言 1.1 声明 本文依据eMMC JEDEC5.1、网络资料及个人工作经验整理而成,如有部分错误请留言。 本文部分内容可能源自网络,侵删。 本文结合eMMC JEDEC5.1协议手册查看效果更佳。 1.2 内容提要 1、什么是可靠性写属性(Write Reliability)? 2、可靠写和普通的写有什么区别? 3、设置可靠写的流程及流程框图。 4、可靠写需要遵循哪些规则? 1.3 参考链接 本文主要参考链接:http://www.up48.com/cn/support/8_37.html 2 什么

黑猫奥利奥的博客 3123

Open3D 进阶(32)渐进三角网(PTD)地面滤波

渐进三角网地面滤波算法(Progressive TIN Densification, PTD)是一种广泛应用于机载LiDAR点云数据处理的滤波方法,旨在从复杂场景中精确分离地面点,以生成数字高程模型(DEM)。

点云侠的博客 1545

蓝桥杯C++练习题 <弗里的语言> 哈希表

首先大概说一下哈希表,我认为就是一个可以高效率查找的记录数据的东西,采用映射的方法将那些数据记录起来,然后映射的不同就分成了好几种方法,常见有直接定址法、除留余数法、数学分析法等等,然后呢由这些映射方法得到其键值又不一定是唯一的,有时候可能出现两个要存储的数对应键值一样,即发生冲突,那么针对解决冲突的方法又分两类,一类叫闭环另一类叫开环(大概这个意思),闭环里面就有像拉链法和溢出表法(多建一个一模一样的,顺序存放,有冲突的就放到这个里面),很多时候溢出表法效率就很高。然后我们有一些比较典型的哈希公式(效..

mc10141222的博客 1190

12306自动抢票系统:基于DrissionPage的智能购票实战

摘要:本文介绍了一个基于DrissionPage的12306自动抢票系统实现方案。该系统通过模拟真实用户操作,实现了车票查询、登录认证、座位选择和订单提交的全流程自动化。项目采用DrissionPage库替代传统Selenium方案,具有更简洁的API设计和更好的性能表现。核心技术包括数据包监听、动作链模拟和反爬虫应对策略,实现了高效可靠的车票抢购功能。系统包含完整的业务流程设计,从环境初始化到最终订单提交,并提供了清晰的数据展示界面。本文强调该项目仅用于技术研究,在实际使用中应严格遵守12306平台规则

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 2791

数据结构---散列表与字符串

文章目录一、散列表(哈希表)1.1 实现一个基于链表法解决冲突问题的散列表1.2 实现一个 LRU 缓存淘汰算法1.3 对应的 LeetCode 练习题二、字符串2.1 实现一个字符集,只包含 a~z 这 26 个英文字母的 Trie 树2.2 实现朴素的字符串匹配算法2.3 对应的 LeetCode 练习题 一、散列表(哈希表) 1.1 实现一个基于链表法解决冲突问题的散列表 (i) 拉链法解...

szyuan的博客 592

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

菜鸡的算法修炼——散列表(第一个只出现一次的字符)

题目描述(引自剑指offer)在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小...

W_J_G_的博客 195

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

构造哈希表之二次探测法

HashTable-散列表/哈希表 是根据关键字(key)而直接访问在内存存储位置的数据结构。 它通过一个关键值的函数将所需的数据映射到表中的位置来访问数据,这个映射函数叫做散列(哈希)函数,存放记录的数组叫做散列表。 构造哈希表的几种方法 1.直接定址法(取关键字的某个线性函数为哈希地址) 2.除留余数法(取关键值被某个不大于散列表长m的数p除后的所得的余数为散列地址) 3.

dream 7万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: ARM 与 MIPS 比较 (X86)
下一篇: qsort的用法
ivan240
博客等级 码龄21年 39粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值