zoukankan      html  css  js  c++  java
  • 字典和散列表

    在字典(或映射)中,用【键/值】对的形式来存储数据。

    // 如果item变量是一个对象的话,需要实现toString方法,否则会导致出现异常的输出结果,如"[object Object]"。
    function defaultToString(item){
        if(item === null){
            return "NULL"
        }else if(item === undefined){
            return "UNDEFINED"
        }else if(typeof item === 'string' || item instanceof 'String'){
            return `${item}`
        }
        return item.toString()
    }
    
    class ValuePair {
        constructor(key,value){
            this.key = key
            this.value = value
        }
        toString(){
            return `[#${this.key}:${this.value}]`
        }
    }
    
    class Dictionary {
        constructor(toStrFn = defaultToString){
            this.toString = toStrFn
            this.table = {}
        }
    }
    Dictionary.prototype.hasKey = function(key){
        return this.table[this.toStrFn(key)] != undefined
    }
    Dictionary.prototype.set = function(key,value){
        if(key != null && value != null){
            const tableKey = this.toStrFn(key)
            this.table[tableKey] = new ValuePair(key,value)
            return true
        }
        return false
    }
    Dictionary.prototype.remove = function(key){
        if(this.hasKey(key)){
            delete this.table[this.toStrFn(key)]
            return true
        }
        return false
    }
    Dictionary.prototype.get = function(key){
        const valuePair = this.table[this.toStrFn(key)]
        return valuePair == null ? undefined : valuePair.value
    
        // if(this.hasKey(key)){
        //     return this.table[this.toStrFn(key)]
        // }
        // return undefined
    }
    Dictionary.prototype.keyValues = function(){
        return Object.value(this.table)
    
        // const vaulePairs = []
        // for(let k in this.table){
        //     if(this.hasKey(k)){
        //         vaulePairs.push(this.table[k])
        //     }
        // }
        // return valuePairs
    }
    Dictionary.prototype.keys = function(){
        return this.keyValues().map(valuePair => valuePair.key)
    }
    Dictionary.prototype.values = function(){
        return this.keyValues().map(valuePair => valuePair.value)
    }
    Dictionary.prototype.foreach = function(callback){
        const valuePairs = this.keyValues()
        for(let i = 0;i < valuePair.length;i++){
            let item = valuePair[i]
            const result = callback(item.key,item.value)
            if(result == false){
                break
            }
        }
    }
    Dictionary.prototype.size = function(){
        return Object.keys(this.table).length
    }
    Dictionary.prototype.isEmpty = function(){
        return this.size() === 0
    }
    Dictionary.prototype.clear = function(){
        this.table = {}
    }
    Dictionary.prototype.toStrFn = function(){
        if(this.isEmpty){
            return ''
        }
        const valuePairs = this.keyValues()
        let baseStr = `${valuePairs[0].toString()}`
        for(let i = 1;i < valuePairs.length;i++){
            baseStr = `${baseStr},${valuePairs[i].toString()}`
        }
        return baseStr
    }  

    散列算法的作用是尽可能快地在数据结构中找到一个值。散列函数的作用是给定一个键值,然后返回值在表中的地址。

    class HashTable {
        constructor(toStrFn = defaultToString){
            this.toString = toStrFn
            this.table = {}
        }
    }
    HashTable.prototype.loseHashCode = function(key){
        if(typeof key === 'number'){
            return key
        }
        const tableKey = this.toStrFn(key)
        let hash = 5381
        for(let i = 0;i < tableKey.length;i++){
            hash = hash * 33 + tableKey.charCodeAt(i)
        }
        return hash % 1013
    }
    HashTable.prototype.hashCode = function(key){
        return this.loseHashCode(key)
    }
    HashTable.prototype.put = function(key,value){
        if(key != null && value != null){
            const pos = this.hashCode(key)
            this.table[pos] = new ValuePair(key,value)
            return true
        }
        return false
    }
    HashTable.prototype.get = function(key){
        const valuePair = this.table[this.toStrFn(key)]
        return valuePair == undefined ? undefined : valuePair.value
    }
    HashTable.prototype.remove = function(key){
        const hash = this.hashCode(key)
        const  valuePair = this.table[hash]
        if(valuePair != null){
            delete this.table[hash]
            return true
        }
        return false
    }

    处理散列表中的冲突(哈希冲突)

    • 分离链接发包括为散列表的每一个位置创建一个链表并将原宿存储在里面。它是解决冲突的最简单的方法,但是在HashTable实例之外还需要额外的空间
    • 线性探查是因为处理冲突的方法是将元素直接存储到表中,而不是在单独的数据结构中。当向表中的某个位置添加一个新元素时,如果索引为position的位置已经被占据了,就尝试position+1的位置。以此类推,直到在散列表中找到一个空闲的位置。
  • 相关阅读:
    AtCoder Beginner Contest 184 ABCDE 题解
    Codeforces Round #685 (Div. 2) C. String Equality 思维
    Codeforces Round #682 (Div. 2) ABC 题解
    Gym 102215 & 队内训练#5
    【题解】 CF436E Cardboard Box 带悔贪心
    【题解】 「NOI2019」序列 模拟费用流 LOJ3158
    【笔记】 exlucas
    【题解】 「HNOI2018」毒瘤 树形dp+动态dp+容斥+格雷码 LOJ2496
    【笔记】 异或高斯消元方案数
    【笔记】 用生成函数推二项式反演
  • 原文地址:https://www.cnblogs.com/zhenjianyu/p/13222099.html
Copyright © 2011-2022 走看看