实用算法实践-第 4 篇 散列表

哈希表算法(闭散列表操作,开散列表操作)创建,查找,插入,删除 #include <stdio.h> #include <malloc.h> #include "stdlib.h" #include <math.h> typedef int Status; typedef int KEYTYPE; typedef struct { KEYTYPE key; }ElemType; typedef struct { ... 阅读详情

4.1    直接寻址表

当关键字的全域比较小时,直接寻址时一种简单而有效的技术。

4.1.1   实例

PKU JudgeOnline, 1200, Crazy Search.

4.1.2   问题描述

给定一个有NC个不同字符的字符串,求出其长度为N的子字符串的个数。例如字符串“daababac”有5个长度为3的子字符串:“daa”、“aab”、“aba”、“bab”、“bac”。

输入保证子字符串的个数不超过16百万个。

4.1.3   输入

34

daababac

4.1.4   输出

5

4.1.5   分析

“输入保证子字符串的个数不超过16百万个”,这个已知条件非常重要。它意味着可以通过。。。。。。。

4.1.6   程序


#include<stdio.h>
#include<string.h>
#define maxNum     16000010
bool hash[maxNum];
char str[maxNum];
int hashSearch(int key)
{
     return key;
}
int hashInsert(int key)
{
     int pos;
     pos = hashSearch(key);
     if(hash[pos]== 0)
     {
         hash[pos] = 1;
         return1;
     }
     return 0;
}
 
int main()
{
     int N;
     int NC;
     int length;
     int count;
     int key;
     int i, j;
     int f[250];
     int num;
     scanf("%d%d",&N,&NC);
    scanf("%s",str);
     memset(hash, 0, sizeof(hash));
     memset(f, 0xFF, sizeof(f));
     length = strlen(str);
     count = 0;
     num = 0;
     for(i = 0;i < length; i++)
     {
         if(f[str[i]]== -1)
         {
              f[str[i]] = num++;
         }
     }
     for(i = 0;i < length - N + 1; i++){
         key = 0;
         for(j =0; j < N; j++){
              key = key * NC + f[str[i + j]];
         }
         count += hashInsert(key);
     }
     printf("%d\n",count);
     return 0;
}

4.2    除法散列表

除法散列发的散列函数为:H(k)= k mod m。其中k为关键字,H(k)将关键字k映射到m个槽的某一个去。

m的选择十分有讲究。可以选作m的值常常是与2的整数幂不太接近的质数。

4.2.1   实例

PKU JudgeOnline, 3349, Snowflake SnowSnowflakes.

4.2.2   问题描述

每个雪花有六个边。如果两个雪花的六个边的长度都一样的话,则它们是一样的。给出一些雪花的六条边,判断其中是不是有两个一样的雪花。

注意:雪花的六条边可能顺时针地给出,也可能逆时针地给出。

4.2.3   输入

2

12 3 4 5 6

4 3 2 1 6 5

4.2.4   输出

Twin snowflakes found.

4.2.5   分析

首先,对与同样的一个雪花,由于存在旋转和镜像的变化,使得给出的六条边的排列不一样。对于给定的一个六条边的各种等效的排列,必须将它映射到同一个唯一的排列。

映射的方法是:将所有等效的排列对应到等效排列中字典序最小的那个排列。

具体的实现方法是:首先找到最短的边,然后判断顺时针和逆时针哪个排列小,取较小的那个。然后继续找到其他最短的边,如果比当前的局部最小排列还小,则修改局部最小排列。如此继续,直到遍历完所有最短的边,所得的局部最小排列就是全局最小的了。

通过上述方法,可以保证的是同一个雪花的任意一种描述都能对应到唯一的一个排列。接下来的做法是将这个排列对应为一个整型关键字。然后使用这个关键字映射到散列中去即可。

采用的具体方法是,将六条边的长度之和作为关键字,并使用除法散列函数。m值取为99991:一个是与2的整数幂不太接近的质数。

4.2.6   程序

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxNum     100002
#define MAX   0x7fffffff
bool hashHead[maxNum];
struct snowflake{
     snowflake *next;
     int used;
     int arm[6];
};
snowflakehash[maxNum];
int arm[6];
snowflake*hashSearch(int key)
{
     snowflake *pointer;
     snowflake *father;
     pointer = &hash[key];
     if((*pointer).used== 0){
         returnpointer;
     }
     while(pointer!= NULL){
         if(memcmp(&((*pointer).arm),arm, sizeof(int)* 6) == 0)
         {
              returnpointer;
         }
         father = pointer;
         pointer = (*pointer).next;
     }
     if(pointer== NULL)
     {
         pointer = (snowflake*)malloc(sizeof(snowflake));
         //memset(pointer,0, sizeof(snowflake));
         (*pointer).next = NULL;
         (*pointer).used = 0;
         (*father).next = pointer;
     }
     returnpointer;
}
int hashInsert(int key)
{
     snowflake *pointer;
     pointer = hashSearch(key);
     if((*pointer).used== 0)
     {
         (*pointer).used = 1;
         memcpy(&((*pointer).arm), arm, sizeof(int) * 6);
         return1;
     }
     return 0;
}
#define magicNumber 99991
#define calKey(sum)    sum %magicNumber
#define shift(i, mode) ((i + 6 + mode) % 6)
#define LEFT -1
#define RIGHT 1
struct sequence
{
     int pos;
     intdirection;
};
int temp[6];
void calMin(sequence *max, sequence *s)
{
     int i;
     int maxPos;
     int sPos;
     intmaxDirection;
     intsDirection;
     maxPos = (*max).pos;
     sPos = (*s).pos;
     maxDirection = (*max).direction;
     sDirection = (*s).direction;
     for(i = 0;i < 6; i++){
         if(temp[maxPos]< temp[sPos]){
              return;
         }else if(temp[sPos] < temp[maxPos]){
              (*max).pos = (*s).pos;
              (*max).direction = (*s).direction;
              //*max =*s;
              return;
         }
         maxPos = shift(maxPos, maxDirection);
         sPos = shift(sPos, sDirection);
     }
}
int main()
{
     int n;
     int i;
     int j;
     int min;
     int minPos;
     int pos;
     intdirection;
     int key;
     int sum;
     sequence s;
     sequence minS;
     memset(hash, 0,sizeof(snowflake));
     scanf("%d",&n);
     for(i = 0;i< n; i++)
     {
         min = MAX;
         for(j =0; j < 6; j++){
              scanf("%d",&temp[j]);
              if(min> temp[j])
              {
                   min = temp[j];
                   minPos = j;
              }
         }
         minS.direction = LEFT;
         minS.pos = minPos;
         s.direction = RIGHT;
         s.pos = minPos;
         calMin(&minS, &s);
         for(j =minPos + 1; j < 6; j++){
              if(temp[j]!= min)
              {
                   continue;
              }
              s.direction = LEFT;
              s.pos = j;
              calMin(&minS, &s);
              s.direction = RIGHT;
              s.pos = j;
              calMin(&minS, &s);
         }
         pos = minS.pos;
         direction =  minS.direction;
         sum = 0;
         for(j =0; j < 6; j++){
              arm[j] = temp[pos];
              sum += temp[pos];
              pos = shift(pos, direction);
         }
         key = calKey(sum);
         if(hashInsert(key)== 0)
         {
              cout << "Twin snowflakes found." <<endl;
              return1;
         }
     }
     cout << "Notwo snowflakes are alike." <<endl;
     return 0;
}
本文章欢迎转载,请保留原始博客链接http://blog.youkuaiyun.com/fsdev/article

在Unity3d使用yolov8的onnx模型 输出OUTPUTS是float32[1,35,8400],表示它会输出一个大小为[1, 35, 8400]的浮点数张量。这个输出张量的维度表示了检测到的目标的数量、每个目标的预测参数以及网格单元的数量。输出张量的第一个维度1表示检测到的目标数量。每个目标由35个值组成,表示目标的类别、置信度、边界框的坐标及10个特定点的位置。要取得8400个数据中置信度最高的数据,然后获取该数据其他channel的数据。运行结果:(蓝色是检测手的边框,红点是自定义的点),其中的四个数字分别表示不同的维度。 阅读详情

相关推荐

企业AI Agent审计与合规:从日志留存到网络联动的完整落地指南

审计日志是企业安全与合规体系的基石,尤其在AI Agent大规模接入业务后,如何完整记录其行为链成为新的挑战。从日志留存180天到PCI DSS合规要求,审计体系需要覆盖会话、推理、工具调用、数据访问等关键环节,并结合不可篡改的存储设计,确保证据链可信。同时,借鉴上网行为管理设备对应用行为控制审计的思路,以及Kismet被动监测网络流量的方法论,将网络侧审计与应用侧日志交叉验证,能有效发现越权和异常行为。本文从日志采集、全链路追踪、基线预警到多租户隔离,系统梳理了AI Agent审计与合规落地的关键路径,帮

weixin_32234493的博客 267

Crazy Search (哈希算法)

Crazy Search 给定一个字符串,其中含有不同的字母数量为m,现在求这个字符串中有多少个长度为n且长的互不相同的字符子串 举个例子, n=3, m=4 ,字符串 “daababac”. 长度为3的不同的子串分别是: “daa”; “aab”; “aba”; “bab”; “bac”. 因此, 答案是5. Input 第一行是两个整数n,m,,一个空格隔开。 接下来一行是...

厄尔尼诺的博客 1248

【汽车ECU标定技术解析】DCM文件与A2L、HEX的协同工作机制

本文深入解析了汽车ECU标定中DCM、A2L与HEX三大核心文件的协同工作机制。A2L文件作为定义标定变量地址与规则的“图纸”,DCM文件承载工程师调试后的具体标定数据,最终通过A2L的地址映射,将DCM数据固化生成可刷入ECU的HEX文件,形成完整的标定数据流转闭环。

weixin_29214559的博客 437

Crazy Search(POJ1200) 分类: poj ...

Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given text. Such number could be the n...

weixin_30955341的博客 175

CloudCompare实战:5分钟搞定点云数据预处理(含常见格式转换技巧)

本文提供了一套基于CloudCompare的5分钟点云数据预处理实战指南。文章详细讲解了如何利用这款开源工具,快速完成点云数据的格式转换(如LAS转PLY)、统计离群值降噪、体素网格下采样以及交互式裁剪等核心操作,帮助用户高效清理和规整杂乱数据,为后续分析建模奠定基础。

weixin_29207533的博客 477

PX4飞控与MAVROS实战:从零搭建无人机ROS通信环境(附常见报错解决)

本文详细介绍了如何从零搭建PX4飞控与ROS的通信环境,重点解析了MAVROS的安装、硬件连接、串口权限配置以及坐标系转换等核心步骤。针对GeographicLib数据下载失败、串口权限不足等常见报错提供了实用解决方案,并附有Offboard模式控制的代码示例,帮助开发者快速建立稳定的无人机ROS开发环境。

dapp9builder的博客 335

poj 1200 Hash处理字符串(简单的rabin-karp)

     把出现过的每个字母映射到对应的数字,这样字符串就变成相应的nc进制数,然后把它转换成10进制,并放入hash[]中,如果是第一次放入,则总数加一。     例如:(此分析出自http://www.cnblogs.com/lxf90/archive/2011/04/19/2021280.html。感谢他。)    3 4daababac d = 3 a = 0 b = 1 c ...

weixin_34405925的博客 168

Transformer实战(1)——词嵌入技术详解

词嵌入的核心思想是,通过将词语表示为稠密的向量,使得计算机可以更有效地处理和理解文本中的语义关系。在本节中,我们学习了单词分布式表示的概念及其实现,包括静态嵌入和动态嵌入,实现了 Word2Vec 和 GloVe 模型,并介绍了如何使用 Gensim API 探索嵌入空间。

盼小辉丶的博客 1万+

poj 3032 Card Trick

Card Trick Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2838 Accepted: 2092 Description The magician shuffles a small pack of cards, holds it face down ...

weixin_30929195的博客 128

音视频开发基础(1):模拟视频技术简介

模拟视频技术是指用模拟技术对动态影像进行捕捉、记来、处理、存储、传输、复现的技术.模拟视频技术的发明、发展与模拟电视系统的发展密不可分.下面将通过模拟电视系统来介绍模拟视频技术中的基本概念. 首先,人的视觉系统的特征为电视等視稿系铳的发明、发展提供了理论依据.光线通过角膜、腫孔、晶状体的折射光线.透过玻璃体到达视网展.视网膜上分布着光感受器,光感受器在光线的剌激下...

琅嬛福地 1493

推免保研夏令营/预推免面试记录—北航网安

链接:https://pan.baidu.com/s/1vkP3EzbVrCc8a7wgQuUZgQ?链接:https://pan.baidu.com/s/1n4EFS2c9WLAfQn91CP4j2g?链接:https://pan.baidu.com/s/1VVNNSfcNDWjXhVhH3MtNjA?上面五个比例基本为:1:5:2:1:1。面试时间:当天上午面试,但是没面完,下午吃了饭之后又继续面试。--来自百度网盘超级会员V5的分享。--来自百度网盘超级会员V5的分享。

admin的博客 3012

哈希表(散列表)C/C++代码实现

哈希表(散列表): 1,构造散列函数 最常用的方法是除留余数法: H(key) = key%p 这个方法的关键是选取适当的p, 一般情况下,可以选p为小于表长的最大质数。例如表长m=100, 可取p=97。 2,处理冲突 选择一个 “好” 的散列函数可以在一定程度上减少冲突,但在实际应用中,很难完全避免发生冲突 1,开放地址法 (1)线性勘测法 (2)二次探测法 (3)伪随机探测法 线性探测法的优点是:只要散列表未填满,总能 找到一个不发生冲突的地址。缺点是:会产生 ”二次聚集“ 现象。而二次探测法和伪随机

Ycy的博客 1万+

ResNet改进(20):融合Swin Transformer与ResNet

这种混合架构的设计理念是:在保留CNN强大局部特征提取能力的同时,引入Transformer的全局建模优势。我们实现的模型在ResNet18的基础上嵌入了一个简化版的Swin Transformer Block,旨在探索两种范式结合的可能性。通过在ResNet早期阶段引入Transformer模块,我们既保留了CNN强大的局部特征提取能力,又获得了Transformer的全局建模优势。本文提出的ResNet与Swin Transformer混合架构,探索了CNN与Transformer结合的可能性。

2401_82355416的博客 859

哈希表(散列表)详解

深入理解哈希表,哈希函数的构造和解决哈希冲突的方法

不能再留遗憾了的博客 2304

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【算法】哈希表

本次为大家带来的是哈希表在算法中的应用与实践,主要讲解哈希表的思路以及在算法题中的应用,本篇文章由于是面向算法党的,对于工程实现部分讲解较为粗糙,以后会在STL中详细讲解工程实现。当然,本篇文章会给出哈希表的两种快速实现,希望大家能将这两个模板理解记忆,方便面试中或者算法竞赛中快速实现。散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。

白晨的博客 3347

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

散列表(哈希表)知识详解

哈希表知识总结

m0_57105290的博客 6515

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

面试八股之集合篇6.1——散列表——散列表(哈希表)HashTable概述

🔥本篇概览:详细讲解了散列表(哈希表)的性质

做一个善良的人,做好自己的事,如果愿意,再发一份光。 971

数据结构与算法(三)散列表篇

在之前,我们已经学习了多种查找数据的方式,比如最简单的,如果数据量不大的情况下,我们可以直接通过顺序查找的方式在集合中搜索我们想要的元素;当数据量较大时,我们可以使用二分搜索来快速找到我们想要的数据,不过需要要求数据按照顺序排列,并且不允许中途对集合进行修改。在学习完树形结构篇之后,我们可以利用二叉查找树来建立一个便于我们查找的树形结构,甚至可以将其优化为平衡二叉树或是红黑树来进一步提升稳定性。

qq_25928447的博客 2278

【算法系列篇】哈希表

算法系列篇-哈希表:两数之和、判定是否为字符重排、存在重复元素、存在重复元素II、字母异位词分组

不能再留遗憾了的博客 2052

哈希表、散列表

1.基本介绍 可能你听过散列表,散列函数,它们跟哈希表,哈希函数是一个概念。接下来以"哈希"来作梳理。 在介绍哈希表的时候,先来比较一下数组和链表的优缺点: 数组:寻址容易,但插入和删除元素比较麻烦; 链表:插入和删除元素容易,但寻址比较麻烦。 那么有没有一种数据结构是既能结合这两种的优点同时也能避免这两种数据结构所带来的缺点呢? 哈希表就是这样的数据结构: 哈希表的底层实际上是基于数组来存储的,当插入键值对时,并不是直接插入该数组中,而是通过对键进行Hash运算得到Hash值,然后和数组容量取模,得到

Deronn的博客 6235

哈希表(散列表)查找的详解

前言博客编写人:Willam 博客编写时间:2017/3/29 博主邮箱:2930526477@qq.com(有志同道合之人,可以加qq交流交流编程心得)1、哈希表查找介绍我之前介绍两种方向的查找算法: 静态查找算法(折半查找、插值查找、斐波那契查找、分块查找) 动态查找算法(二叉排序树、平衡二叉树、B-树、B+树) 但是,这些查找算法都是通过从表头开始,挨个挨个的比较记录,才得到我们需要查找的关键

William 8310

哈希表(散列表)原理详解

哈希表(散列表)原理详解

那年聪聪 30万+

算法 中的 散列表(哈希表)

散列表又叫做哈希表(Hash Table),是一种提供了键(Key)值(Value)映射关系的一种数据结构。 只要给出一个Key值,就可以快速匹配出Value值。正是因为这个特性,比如有一本词典,它就可以给出一个单词,去快速找出它的解释。 什么是哈希函数? 首先,因为前面说过,数组的查询效率是最快的,数组可以根据数组的下标,直接对元素进行随机访问,所以,散列表想要查询快的话,其本质...

Seas.Su的博客 349

【优选算法之哈希表】No.11--- 经典哈希表算法

【优选算法之哈希表】No.11--- 经典哈希表算法

小沈.的博客 1333
上一篇: 实用算法实践-第 3 篇 堆排序
下一篇: 实用算法实现-第 5 篇 二分查找树
存储李希
博客等级 码龄15年 418粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值