哈希表-(数值+字符串)

哈希-数组

数值

1.拉链法

--注意
1。取模取成最小的质数-判断条件
 *         int j =100001;
 *         int m=0;
 *         while (m<1){
 *             if(panduan(j)){
 *                 m++;
 *                 System.out.println(j);
 *                 j++;
 *             }else {j++;}
 *
 *         }
 * 2。每个链表的0不存放值,作为结束点条件
 * static int index=1;
 * 3。输出的时候按照链表的形式输出
 *         int k = (x%N+N)%N;
 *         for(int i=h[k];i!=0;i=next[i]){
 *             if(e[i] == x)return true;
 *         }
 *         return false;
 */
package 大学菜;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;

/*
* */
public class 哈希表拉链法2 {
    //判断质数
    static int N = 100003;
    static int[] h = new int[N];
    static int[] next = new int[N];
    static int[] e = new int[N];
    static int index=1;//为了保证头节点指向是0。

    public static void insert(int x){
        //取模
        int k = (x % N + N) % N;
        //找位置
        e[index] = x;//先放好值,值和位置是两个不同的概念
        next[index] = h[k];//这个地方找的是位置
        h[k] = index;
        index++;
    }
    public static boolean query(int x){
        //Q x,询问数 x 是否在集合中出现过;
        //先找位置
        int k = (x%N+N)%N;
        for(int i=h[k];i!=0;i=next[i]){
            if(e[i] == x)return true;
        }
        return false;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.valueOf(reader.readLine());
        while (n-->0){
            String[] s = reader.readLine().split(" ");
            String action = s[0];
            if(action.equals("I")){
                int x = Integer.valueOf(s[1]);
                insert(x);
            }else {
                int x = Integer.valueOf(s[1]);
                if(query(x)){System.out.println("Yes");}
                else {System.out.println("No");}
            }
        }
    }
}

开放寻址法

注意:
/*开放寻址法
1.模数的寻找同拉链法。
2.数组范围定成原定要求的2-3倍
* 2。k个查找-如果有一直往后查找
* 1。添加
* 2。查找
* 3。删除-打标记进行删除-类似于查找的特殊
* */
package 大学菜;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class 哈希表开放寻址法2 {
    //1.开辟空间大
    static int N = 2000003;
    static int[] h = new int[N];
    //定一个超大值,开始的时候让他们都等于这个值
    static int ull = (int)(1e9+1);
    public static void insert(int x){
        //模求地址
        int k = (x%N+N)%N;
        //冲突情况:当前位置不为空,并且不为x
        while(h[k] != ull && h[k] != x){//位置不空,且x不存在
            k ++;
            if(k == N) k = 0; //末尾,从头开始
        }
        h[k] = x;
    }
    public static boolean query(int x){
        int k= (x%N+N)%N;
        while (h[k]!=ull){
            if(h[k] == x){
                return true;
            }else {
                k++;
                if( k==N) k=0;
            }
        }
        return false;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.valueOf(reader.readLine());
        for(int i=0 ;i<N;i++){
            h[i] = ull;
        }
        while (n-->0){
            String[] s = reader.readLine().split(" ");
            String action = s[0];
            if(action.equals("I")){
                int x = Integer.valueOf(s[1]);
                insert(x);
            }else {
                int x = Integer.valueOf(s[1]);
                if(query(x)){System.out.println("Yes");}
                else {System.out.println("No");}
            }
        }
    }
}

字符串

字符串哈希值时。
使用进制的概念
在这里插入图片描述

字符串哈希(步骤):
1. 先将原字符串的所有前缀的哈希求出 (h[i] = h[i - 1] * P + str[i])
2. 用对应的公式求出对应区间的哈希值是否一样—> 区间[l,r]中的哈希值为:h[r]-h[l-1]*p[r-l+1]
3. 每次都要对h数组取模(%Q)

代码:

package 大学菜;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

/*
1.进制P=131
2.哈希值公式:h[i] = h[i-1] * P + str[i]
3.字符串区间公式是否相同公式: h[r] - h[l-1]*p[r-l+1]**/
public class 哈希字符串2 {
    static int P = 131;
    static int N =100010;
    static long[] p = new long[N];
    static long[] h = new long[N];

    public static long get(int l,int r){
        return h[r]-h[l-1]*p[r-l+1];
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] s = reader.readLine().split(" ");
        int n = Integer.valueOf(s[0]);
        int m = Integer.valueOf(s[1]);
        p[0] = 1;//防止数据出现全0
        String str = reader.readLine();
        for(int i=1;i<=n;i++){
            p[i] = p[i-1]*P;//数组保存的是每个不同的进制数
            h[i] = h[i-1]*P + str.charAt(i-1);//每位不同的哈希值
        }
        //判断
        while (m-->0){
            String[] str2 = reader.readLine().split(" ");
            int l1 = Integer.valueOf(str2[0]);
            int r1 = Integer.valueOf(str2[1]);
            int l2 = Integer.valueOf(str2[2]);
            int r2 = Integer.valueOf(str2[3]);
            //判断是否哈希值相同
            if (get(l1,r1) == get(l2,r2)){
                System.out.println("Yes");
            }else {System.out.println("No");}
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值