zoukankan      html  css  js  c++  java
  • 数据结构与算法——哈希函数与哈希表等(1)

    认识哈希函数和哈希表的实现

    MD5 表达16^16范围的值 SHal 表达16^32范围的值

    输入相同,即输出相同,不随机

    不同的输出,输出相同

    均匀性,离散性

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map.Entry;
    
    public class HashMap {
    
    	public static void main(String[] args) {
    		HashMap<String, String> map = new HashMap<>();
    		map.put("zuo", "31");
    
    		System.out.println(map.containsKey("zuo"));
    		System.out.println(map.containsKey("chengyun"));
    
    		System.out.println(map.get("zuo"));
    		System.out.println(map.get("chengyun"));
    
    		System.out.println(map.isEmpty());
    		System.out.println(map.size());
    
    		System.out.println(map.remove("zuo"));
    		System.out.println(map.containsKey("zuo"));
    		System.out.println(map.get("zuo"));
    		System.out.println(map.isEmpty());
    		System.out.println(map.size());
    
    		map.put("zuo", "31");
    		System.out.println(map.get("zuo"));
    		map.put("zuo", "32");
    		System.out.println(map.get("zuo"));
    
    		map.put("zuo", "31");
    		map.put("cheng", "32");
    		map.put("yun", "33");
    
    		for (String key : map.keySet()) {
    			System.out.println(key);
            }
    
    		for (String values : map.values()) {
    			System.out.println(values);
    		}
    
    		map.clear();
    		map.put("A", "1");
    		map.put("B", "2");
    		map.put("C", "3");
    		map.put("D", "1");
    		map.put("E", "2");
    		map.put("F", "3");
    		map.put("G", "1");
    		map.put("H", "2");
    		map.put("I", "3");
    		for (Entry<String, String> entry : map.entrySet()) {
    			String key = entry.getKey();
    			String value = entry.getValue();
    			System.out.println(key + "," + value);
    		}
    		// you can not remove item in map when you use the iterator of map
    //		 for(Entry<String,String> entry : map.entrySet()){
    //			 if(!entry.getValue().equals("1")){
    //				 map.remove(entry.getKey());
    //			 }
    //		 }
    		// if you want to remove items, collect them first, then remove them by
    		// this way.
    		List<String> removeKeys = new ArrayList<String>();
    		for (Entry<String, String> entry : map.entrySet()) {
    			if (!entry.getValue().equals("1")) {
    				removeKeys.add(entry.getKey());
    			}
    		}
    		for (String removeKey : removeKeys) {
    			map.remove(removeKey);
    		}
    		for (Entry<String, String> entry : map.entrySet()) {
    			String key = entry.getKey();
    			String value = entry.getValue();
    			System.out.println(key + "," + value);
    		}
    	}
    }
    

    设计RandomPool结构

    设计一种结构,在该结构中有如下三个功能:

    insert (key):将某个key加入到该结构,做到不重复加入 delete (key):将原本在结构中的某个key移除 getRandom():等概率随机返回结构中的任何一个key。

    【要求】

    Insert、 delete和getRandom方法的时间复杂度都是0 (1)

    import java.util.HashMap;
    
    public class RandomPool {
    
    	public static class Pool<K> {
    		private HashMap<K, Integer> keyIndexMap;
    		private HashMap<Integer, K> indexKeyMap;
    		private int size;
    
    		public Pool() {
    			this.keyIndexMap = new HashMap<K, Integer>();
    			this.indexKeyMap = new HashMap<Integer, K>();
    			this.size = 0;
    		}
    
    		public void insert(K key) {
    			if (!this.keyIndexMap.containsKey(key)) {
    				this.keyIndexMap.put(key, this.size);
    				this.indexKeyMap.put(this.size++, key);
    			}
    		}
    
    		public void delete(K key) {
    			if (this.keyIndexMap.containsKey(key)) {
    				int deleteIndex = this.keyIndexMap.get(key);
    				int lastIndex = --this.size;
    				K lastKey = this.indexKeyMap.get(lastIndex);
    				this.keyIndexMap.put(lastKey, deleteIndex);
    				this.indexKeyMap.put(deleteIndex, lastKey);
    				this.keyIndexMap.remove(key);
    				this.indexKeyMap.remove(lastIndex);
    			}
    		}
    
    		public K getRandom() {
    			if (this.size == 0) {
    				return null;
    			}
    			int randomIndex = (int) (Math.random() * this.size); // 0 ~ size -1
    			return this.indexKeyMap.get(randomIndex);
    		}
    
    	}
    
    	public static void main(String[] args) {
    		Pool<String> pool = new Pool<String>();
    		pool.insert("zuo");
    		pool.insert("cheng");
    		pool.insert("yun");
    		System.out.println(pool.getRandom());
    		System.out.println(pool.getRandom());
    		System.out.println(pool.getRandom());
    		System.out.println(pool.getRandom());
    		System.out.println(pool.getRandom());
    		System.out.println(pool.getRandom());
    	}
    }
    

    详解布隆过滤器

    n=样本量 p=失误率

    m = -n * ln p / (ln 2)^2 空间大小

    k = ln 2 * m/n 约等于 0.7 * m/n

    p真 = (1 - e ^ (-n * k真 / m真))^k真

    位图

    public class BitMap {
    	public static void main(String[] args) {
    
    		int a = 0;		
    		// a  32 bit
    		int[] arr = new int[10]; // 32bit * 10 -> 320 bits
    		
    		// arr[0]  int  0  ~ 31
    		// arr[1]  int  32 ~ 63
    		// arr[2]  int  64 ~ 95
    
    		int i = 178; // 想取得178个bit的状态
    		int numIndex = i / 32;
    		int bitIndex = i % 32;
    		
    		// 拿到178位的状态
    		int s = (      (arr[numIndex] >> (bitIndex))        & 1);
            // 请把178位的状态改成1
    		arr[numIndex] = arr[numIndex] | (1 << (bitIndex));
    		i = 178; // 请把178位的状态改成0
    		arr[numIndex] = arr[numIndex] & (~   (1 << bitIndex)  );
    		i = 178; // 请把178位的状态拿出来
    		// bit 0 1
    		int bit = (arr[i / 32] >> (i % 32)) & 1;
    	}
    }
    

    详解一致性哈希原理

    https://www.jianshu.com/p/e968c081f563

    岛问题

    一个矩阵中只有。和1两种值,每个位置都可以和自己的上、下、左、右 四个位置相连,如 果有一片1连在一起,这个部分叫做一个岛,求一个矩阵中有多少个岛?

    【举例】

    001010

    111010 100100 000000

    这个矩阵中有三个岛 【进阶】如何设计一个并行算法解决这个问题

    public class Code03_Islands {
    
    	public static int countIslands(int[][] m) {
    		if (m == null || m[0] == null) {
    			return 0;
    		}
    		int N = m.length;
    		int M = m[0].length;
    		int res = 0;
    		for (int i = 0; i < N; i++) {
    			for (int j = 0; j < M; j++) {
    				if (m[i][j] == 1) {
    					res++;
    					infect(m, i, j, N, M);
    				}
    			}
    		}
    		return res;
    	}
    
    	public static void infect(int[][] m, int i, int j, int N, int M) {
    		if (i < 0 || i >= N || j < 0 || j >= M || m[i][j] != 1) {
    			return;
    		}
    		// i,j没越界,并且当前位置值是1
    		m[i][j] = 2;
    		infect(m, i + 1, j, N, M);
    		infect(m, i - 1, j, N, M);
    		infect(m, i, j + 1, N, M);
    		infect(m, i, j - 1, N, M);
    	}
    
    	public static void main(String[] args) {
    		int[][] m1 = {  { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    				        { 0, 1, 1, 1, 0, 1, 1, 1, 0 }, 
    				        { 0, 1, 1, 1, 0, 0, 0, 1, 0 },
    				        { 0, 1, 1, 0, 0, 0, 0, 0, 0 }, 
    				        { 0, 0, 0, 0, 0, 1, 1, 0, 0 }, 
    				        { 0, 0, 0, 0, 1, 1, 1, 0, 0 },
    				        { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, };
    		System.out.println(countIslands(m1));
    
    		int[][] m2 = {  { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    						{ 0, 1, 1, 1, 1, 1, 1, 1, 0 }, 
    						{ 0, 1, 1, 1, 0, 0, 0, 1, 0 },
    						{ 0, 1, 1, 0, 0, 0, 1, 1, 0 }, 
    						{ 0, 0, 0, 0, 0, 1, 1, 0, 0 }, 
    						{ 0, 0, 0, 0, 1, 1, 1, 0, 0 },
    						{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, };
    		System.out.println(countIslands(m2));
    	}
    }
    

    并查集结构的详解和实现

    import java.util.HashMap;
    import java.util.List;
    import java.util.Stack;
    
    public class Code04_UnionFind {
    
    	// 样本进来会包一层,叫做元素
    	public static class Element<V> {
    		public V value;
    
    		public Element(V value) {
    			this.value = value;
    		}
    	}
    
    	public static class UnionFindSet<V> {
    		public HashMap<V, Element<V>> elementMap;
    		// key  某个元素  value 该元素的父
    		public HashMap<Element<V>, Element<V>> fatherMap;
    		// key 某个集合的代表元素   value 该集合的大小
    		public HashMap<Element<V>, Integer> sizeMap;
    
    		public UnionFindSet(List<V> list) {
    			elementMap = new HashMap<>();
    			fatherMap = new HashMap<>();
    			sizeMap = new HashMap<>();
    			for (V value : list) {
    				Element<V> element = new Element<V>(value);
    				elementMap.put(value, element);
    				fatherMap.put(element, element);
    				sizeMap.put(element, 1);
    			}
    		}
    
    		// 给定一个ele,往上一直找,把代表元素返回
    		private Element<V> findHead(Element<V> element) {
    			Stack<Element<V>> path = new Stack<>();
    			while (element != fatherMap.get(element)) {
    				path.push(element);
    				element = fatherMap.get(element);
    			}
    			while (!path.isEmpty()) {
    				fatherMap.put(path.pop(), element);
    			}
    			return element;
    		}
    
    		public boolean isSameSet(V a, V b) {
    			if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
    				return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
    			}
    			return false;
    		}
    
    		public void union(V a, V b) {
    			if (elementMap.containsKey(a) && elementMap.containsKey(b)) {
    				Element<V> aF = findHead(elementMap.get(a));
    				Element<V> bF = findHead(elementMap.get(b));
    				if (aF != bF) {
    					Element<V> big = sizeMap.get(aF) >= sizeMap.get(bF) ? aF : bF;
    					Element<V> small = big == aF ? bF : aF;
    					fatherMap.put(small, big);
    					sizeMap.put(big, sizeMap.get(aF) + sizeMap.get(bF));
    					sizeMap.remove(small);
    				}
    			}
    		}
    	}
    }
    
  • 相关阅读:
    (转)大型网站架构演变和知识体系
    最小生成树-Prim算法和Kruskal算法
    最短路径——Floyd-Warshall算法
    SpringBootService,一个基于spring boot搭建的SOA服务框架
    Netty(六)UDP在netty中的使用
    Netty(五)序列化protobuf在netty中的使用
    Netty(四)分隔符与定长解码器的使用
    Netty(三)TCP粘包拆包处理
    Netty(二)入门
    Netty(一)引题
  • 原文地址:https://www.cnblogs.com/wwj99/p/12240289.html
Copyright © 2011-2022 走看看