当前位置: 首页 > news >正文

算法-哈希表和相关练习-java

哈希表

哈希表存储方式:1.开放寻址法,2.拉链法

运用:把一个很大的空间映射到比较小的范围(110^9->110^5)

模拟散列表

开放寻址法:直接一个数组模拟蹲坑

1.x mod 10^5(最好质数并且离2的n整次幂尽量远) 2.对于冲突,当前位置有数了就对位置+1直到当前没数为止,一般需要开当前范围的两到三倍,然后定义一个0x3f3f3f是大于10^9的一个数(在最大范围外)

代码:

import java.util.Scanner;
public class Main{static int N = 200003,idx;static int nulls = 0x3f3f3f3f;//最大的数static int[] h = new int[N];public static int find(int x){int k = (x % N + N) % N;while(h[k]!=nulls && h[k] != x){//不为空且没找到就继续找k++;if(k==N) k=0;//到结尾了从头开始}return k;}public static void main(String[] args){Scanner scan = new Scanner(System.in);int n = scan.nextInt();for(int i = 0; i<N;i++)h[i]=0x3f3f3f3f;while(n -- > 0){String s = scan.next();int x = scan.nextInt();int k = find(x);if(s.equals("I")){     h[k]=x;}else{if(h[k]!=nulls) System.out.println("Yes");else System.out.println("No");}}}
}

拉链法:假设映射到1~10^5内,相当于每个数字的位置都是一个链表,有冲突就插入到当前链表最后面这样

import java.util.Scanner;
public class Main{static int N = 100003,idx;static int[] h = new int[N];static int[] e = new int[N];static int[] ne = new int[N];public static void insert(int x){int k = (x % N + N) % N;//存储下标位置 防止负数e[idx] = x;//赋值ne[idx] = h[k];//该点指向下一个节点h[k] = idx++;//头指向该节点}public static boolean find(int x){int k = (x % N + N) % N;for(int i = h[k];i != -1;i = ne[i]){if(e[i] == x){return true;}    }return false;}public static void main(String[] args){Scanner scan = new Scanner(System.in);int n = scan.nextInt();idx = 0;for(int i = 0; i<N;i++)h[i]=-1;while(n -- > 0){String x = scan.next();if(x.equals("I")){int a = scan.nextInt();insert(a);}else{int b = scan.nextInt();if(find(b)) System.out.println("Yes");else System.out.println("No");}}}
}

字符串哈希

在这里插入图片描述

代码

import java.util.Scanner ;
public class Main{//开的是long类型数组,本来是需要进行前缀hash求完之后需要进行模2的64次方来防止相同的冲突,可能超过我们给的数组大小static int N = 100010,P = 131;//p是进制数,惊艳值static long[] h = new long[N];//这是存放hash前缀值得数组static long[] p = new long[N];//这是存放p的n次方的数组public static long get(int l,int r){//这里是将运用了一点前缀和公式的方式进行计算//求l-r区间的hash值,就要用h[r] - h[l-1],因为两者位数不用需要让h[l-1]向左边移到跟h[r]对齐//就比如求1234的3-4区间位,1234 - 12,12左移然后就让12*10^(4-3+1)=12*10^2=1200,然后1234-1200 = 34,这样进行计算出来//然后本题是p进制,所以需要将上面公式中的10换成p就行了//h[0] = 0//h[1] = h[i-1] * P + str[1] = 0*P+a = a//h[2] = a * P + b//h[3] = (a*P+b)*P+c = a*p[2]+b*P+c//h[4] = (a*p[2]+b*P+c)*P+d = a*p[3]+b*p[2]+c*P+d//比如abcd求3-4区间位,就是让h[d]-h[b],h[b]位数不用需要向左移对齐h[d],//h[2]*P^(4-3+1)=(a*P+b)*P^2 = a*P^3+b*P^2//然后就让h[d] - h[b]求出34区间值,(a*p[3]+b*p[2]+c*P+d) - (a*P^3+b*P^2) = c*P+dreturn h[r] - h[l-1]*p[r-l+1];}public static void main(String[] args){Scanner scan = new Scanner(System.in);int n = scan.nextInt();int m = scan.nextInt();String s = scan.next();p[0] = 1;//这个是p的0次方的值,需要单独写出来,非常重要for(int i = 1 ; i <= n ; i++ ){p[i] = p[i-1] * P;//这里对应每一个下标对应对应P的多少次方h[i] = h[i-1] * P + s.charAt(i-1);//这里是公式,预处理前缀哈希的值,因为是P进制,所以中间乘的是P}while(m -- > 0){int l1 = scan.nextInt();int r1 = scan.nextInt();int l2 = scan.nextInt();int r2 = scan.nextInt();//判断两个区间是不是相同,用get的方法返回值一样说明区间的hash值是一样的if(get(l1,r1) == get(l2,r2)) System.out.println("Yes");else System.out.println("No");}}
}
http://www.dtcms.com/a/594069.html

相关文章:

  • 新上线的网站怎么做优化asp网站默认后台
  • CSS浮动样式
  • 华能集团网站建设方案项目分析网络优化公司哪家好
  • 做网站有哪些主题wordpress cms
  • k8s中的StatefulSet 控制器
  • web开发,在线%餐饮自动化管理%系统,基于idea,html,css,jquery,jsp,java,jdk,maven,ssm,mysql。
  • 西安网站排名公司门户网站自查报告
  • 网站设计配色案列青岛网站seo推广
  • 蓝牙钥匙 第78次 蓝牙与区块链技术融合:构建去中心化物联网安全新范式
  • Ubuntu Desktop Linux 文件和文件夹操作命令详解
  • 兰州市建设工程招标投标中心网站廊坊网站建设公司费用
  • 【论文调研】NASA任务负荷指数(NASA-TLX)V1.0 总结
  • Spark 中 distribute by、sort by、cluster by 深度解析
  • 外贸网站平台都有哪些平台wordpress安装博客
  • 长春网站建设企业wordpress 取消评论
  • 电商网站设计制作网站建设与设计实习报告
  • C++ 设计模式《业务模块的调度室》
  • 南京电商网站开发网业上有错误怎么解决
  • MongoDB 操作命令
  • python和mongodb交互
  • 网站建设就业前景学校网站建设栏目设置
  • 文心一言5.0 Preview模型能力观察:基于LMArena排名的文本任务实测
  • 2-物理层
  • 数据入仓和数据ETL(七)
  • 怎么做网站评估遵义网站
  • Makefile常见错误与快速修复指南
  • 嵌入式Linux学习——文件目录
  • 中科院网站建设WordPress做头部的插件
  • python做网站有什么弊端台州seo网站排名优化
  • PostgreSQL基操