散列(哈希)及其练习题(基础)

2024-05-26 01:44
文章标签 基础 练习题 哈希 散列

本文主要是介绍散列(哈希)及其练习题(基础),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

散列

字符出现次数

 力扣经典题:两数之和

 集合运算

并 

差 

 字符串的出现次数


散列

导入:

有N个数和M个数,如何判断M个数中每个数是否在N中出现?

思想:空间换时间

创建hashtable,以N个数本身为索引(数组下标)构建 bool hashtable

输入x的过程中,hashtable[x]=True(若要计算出现次数,换成++)

但终归是有局限性!数字只能是整数,还不能太大,等等。

散列函数:平房区中法、取余数……

可能会冲突:(即:不是单射了)

 字符串哈希:借鉴26进制的推广:62进制

字符是否出现

 如何判断输完了?

本地devc++我可以说:c1!='\n',c1!=' ','a'<=c1<='z'都能跑,如

#include<stdio.h>
#include<string>
using namespace std;
int main()
{printf("%d",'\n'>='a');
//    char c1[27];
char c1;char c2[27]={0};
int i=0;
scanf("%c",&c1);
while(c1>='a'&&c1<='z')
{c2[c1-'a']++;scanf("%c",&c1);
}
for(int j=0;j<26;j++)
if(c2[j]>0) printf("%c %d\n",'a'+j,c2[j]);
}

然而网站上不行,得用while(scanf("%c",&c1)!=EOF)
 

#include<stdio.h>
#include<string>
using namespace std;
int main()
{
//    char c1[27];
char c1;char c2[27]={0};
int i=0;
// scanf("%c",&c1);
while(scanf("%c",&c1)!=EOF)
{c2[c1-'a']++;// scanf("%c",&c1);
}
for(int j=0;j<26;j++)
if(c2[j]>0) printf("%c %d\n",'a'+j,c2[j]);
}

 这个本地不能跑了。。

行吧,得改头换面用cstring

字符出现次数

 这里我忘了这个:

就算你定义char a[1000],如果赋值“avx”,仍然可以使用长度strlen,仍为3

我的代码

#include<stdio.h>
#include<cstring>
using namespace std;
int main()
{char s1[1001],s2[1001];int s[26]={0};scanf("%s",&s1);scanf("%s",&s2);for(int i=0;s1[i]>='a'&&s1[i]<='z'&&i<1001;i++)s[s1[i]-'a']=1;for(int i=0;s2[i]>='a'&&s2[i]<='z'&&i<1001;i++)
{if(i==0)		printf("%d",s[s2[i]-'a']);else	printf(" %d",s[s2[i]-'a']);
}}

 答案

#include <cstdio>
#include <cstring>const int MAXN = 26;
const int MAXL = 1001;
char str1[MAXL], str2[MAXL];
bool hashTable[MAXN] = {false};int getHashKey(char c) {return c - 'a';
}int main () {scanf("%s%s", str1, str2);int len1 = strlen(str1);int len2 = strlen(str2);for (int i = 0; i < len1; i++) {hashTable[getHashKey(str1[i])] = true;}for (int i = 0; i < len2; i++) {printf("%d", hashTable[getHashKey(str2[i])]);printf(i < len2 - 1 ? " " : "\n");}return 0;
}

 力扣经典题:两数之和

简单版

 我的代码(devc++int数组长度设为1000000报错,但是网上通过了)

 #include<stdio.h>
#include<cstring>
using namespace std;
int main()
{
int n,k;
scanf("%d %d",&n,&k);
int A[n];
int h[1000000]={0};
int ans=0;
int a0=0;
for(int i=0;i<n;i++)
{scanf("%d",&a0);A[i]=a0;h[A[i]]++;	 
}for(int i=0;i<n;i++)
{
if(k>=A[i])
{
if(A[i]<=k-A[i])
{if(A[i]==k-A[i]){if(h[A[i]]>1)ans++;//printf("-%d-",A[i]);	}else if(h[k-A[i]]>0) ans++;//printf("-%d-",A[i]);
}
else break;
}
}
printf("%d",ans);}

答案(他是遍历整个,再除以二) 

#include <cstdio>const int MAXN = 100000;
const int MAXK = 1000001;
int a[MAXN], hashTable[MAXK] = {false};int main () {int n, k;scanf("%d%d", &n, &k);for (int i = 0; i < n; i++) {scanf("%d", &a[i]);hashTable[a[i]] = true;}int ans = 0;for (int i = 0; i < n; i++) {if (k - a[i] >= 0 && hashTable[k - a[i]]) {ans++;}}printf("%d", ans / 2);return 0;
}

 集合运算

思路:第一个数组构造哈希表,然后遍历第二个,输出值为1者

数组长度10001错误,数组长度20000,通过。。

#include<stdio.h>
#include<cstring>
using namespace std;
int main()
{
int n1,n2;
scanf("%d %d",&n1,&n2);
int A[n1],B[n2],h1[20010],h2[20010];
int a0=0;
for(int i=0;i<n1;i++)
{scanf("%d",&a0);A[i]=a0;h1[A[i]]++;	 
}
bool flag=0;
for(int i=0;i<n2;i++)
{scanf("%d",&a0);B[i]=a0;//求交集:if(h1[a0]) {if(flag) printf(" %d",a0);else printf("%d",a0);flag=1;} 
//	h2[B[i]]++;	 
}}

并 

 思路:遍历第一个数组构造哈希表,然后遍历第二个,把第一个为0的但第二个出现的数字的哈希值改为1,最后遍历整个表,输出值为1的

#include<stdio.h>
#include<cstring>
using namespace std;
int main()
{
int n1,n2;
scanf("%d %d",&n1,&n2);
int A[n1],B[n2],h1[20000]={0},h2[20000]={0};
int a0=0;
for(int i=0;i<n1;i++)
{scanf("%d",&a0);A[i]=a0;h1[A[i]]++;	 
}
bool flag=0;
for(int i=0;i<n2;i++)
{scanf("%d",&a0);B[i]=a0;//求交集:
//	if(h1[a0]) 
//	{
//		if(flag) printf(" %d",a0);
//		else printf("%d",a0);
//		flag=1;
//	} 
//并集if(!h1[a0]) h1[a0]++;
}
//并集:整个儿遍历10000?for(int i=0;i<20000;i++)
if (h1[i])
{if(flag) printf(" %d",i);else printf("%d",i);flag=1;}		}

差 

 思路:遍历第一个造出哈希表,遍历第二个,每找一个,哈希表对应值-1;最后遍历第一个集合,每输出一次,哈希值-1,直至为0

#include<stdio.h>
#include<cstring>
using namespace std;
int main()
{
int n1,n2;
scanf("%d %d",&n1,&n2);
int A[n1],B[n2],h1[20000]={0},h2[20000]={0};
int a0=0;
for(int i=0;i<n1;i++)
{scanf("%d",&a0);A[i]=a0;h1[A[i]]++;	 
}
bool flag=0;
for(int i=0;i<n2;i++)
{scanf("%d",&a0);B[i]=a0;
//求差集 if(h1[a0]) h1[a0]--;
}
for(int i=0;i<n1;i++)	
{while(h1[A[i]]){if(flag) printf(" %d",A[i]);else printf("%d",A[i]);flag=1;h1[A[i]]--;}} 
}//求交集:
//	if(h1[a0]) 
//	{
//		if(flag) printf(" %d",a0);
//		else printf("%d",a0);
//		flag=1;
//	} 
//并集
// 	if(!h1[a0]) h1[a0]++;
//}
//并集:整个儿遍历10000?
//for(int i=0;i<20000;i++)
//if (h1[i])
//{if(flag) printf(" %d",i);
//		else printf("%d",i);
//		flag=1;
//		}		

 字符串的出现次数

我:

#include<stdio.h>
#include<cstring>
using namespace std;
int abc(char str[4])
{return (str[0]-'A')*26*26+(str[1]-'A')*26+(str[2]-'A');
}int main()
{int n1,n2;scanf("%d",&n1);
char s1[n1+1][5];
int si1[20000]={0};
for(int i=0;i<n1;i++)
{scanf("%s",s1[i]);
//	printf("%d",abc(s1[i]));si1[abc(s1[i])]++;
//	printf("%s&%d",s1[i],si1[abc(s1[i])]);}
scanf("%d",&n2);
char s2[n2+1][5];
for(int i=0;i<n2;i++)
{scanf("%s",s2[i]);if (si1[abc(s2[i])]) printf("%d",si1[abc(s2[i])]);else printf("0");if (i<n2-1) printf(" ");}//COD
//ABA}

 答案

#include <cstdio>const int MAXN = 26 * 26 * 26;
const int MAXL = 1001;
char str[MAXL];
int hashTable[MAXN] = {0};int getHashKey(char s[]) {return (s[0] - 'A') * 26 * 26 + (s[1] - 'A') * 26 + (s[2] - 'A');
}int main () {int n, m;scanf("%d", &n);for (int i = 0; i < n; i++) {scanf("%s", str);hashTable[getHashKey(str)]++;}scanf("%d", &m);for (int i = 0; i < m; i++) {scanf("%s", str);printf("%d", hashTable[getHashKey(str)]);printf(i < m - 1 ? " " : "\n");}return 0;}

这篇关于散列(哈希)及其练习题(基础)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003208

相关文章

从基础到进阶详解Pandas时间数据处理指南

《从基础到进阶详解Pandas时间数据处理指南》Pandas构建了完整的时间数据处理生态,核心由四个基础类构成,Timestamp,DatetimeIndex,Period和Timedelta,下面我... 目录1. 时间数据类型与基础操作1.1 核心时间对象体系1.2 时间数据生成技巧2. 时间索引与数据

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

python操作redis基础

《python操作redis基础》Redis(RemoteDictionaryServer)是一个开源的、基于内存的键值对(Key-Value)存储系统,它通常用作数据库、缓存和消息代理,这篇文章... 目录1. Redis 简介2. 前提条件3. 安装 python Redis 客户端库4. 连接到 Re

SpringBoot基础框架详解

《SpringBoot基础框架详解》SpringBoot开发目的是为了简化Spring应用的创建、运行、调试和部署等,使用SpringBoot可以不用或者只需要很少的Spring配置就可以让企业项目快... 目录SpringBoot基础 – 框架介绍1.SpringBoot介绍1.1 概述1.2 核心功能2

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

Spring Boot集成SLF4j从基础到高级实践(最新推荐)

《SpringBoot集成SLF4j从基础到高级实践(最新推荐)》SLF4j(SimpleLoggingFacadeforJava)是一个日志门面(Facade),不是具体的日志实现,这篇文章主要介... 目录一、日志框架概述与SLF4j简介1.1 为什么需要日志框架1.2 主流日志框架对比1.3 SLF4

Spring Boot集成Logback终极指南之从基础到高级配置实战指南

《SpringBoot集成Logback终极指南之从基础到高级配置实战指南》Logback是一个可靠、通用且快速的Java日志框架,作为Log4j的继承者,由Log4j创始人设计,:本文主要介绍... 目录一、Logback简介与Spring Boot集成基础1.1 Logback是什么?1.2 Sprin

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键