哈希表以及用js封装一个哈希表

2023-11-15

最近在学数据结构和算法,正好将学习的东西记录下来,我是跟着一个b站博主学习的,是使用js来进行讲解的,待会也会在文章后面附上视频链接地址,大家想学习的可以去看看

 本文主要讲解哈希表,其他数据结构后续学完也会持续更新!

目录

一、什么是哈希表

下面是 chatGPT 给出的解释:

下面是PPT中的讲解

 想要学习哈希表,那就不得不了解一些哈希表的概念

 二、哈希化时产生的问题:冲突 

注意:常见解决冲突的方法有两种,链地址法(拉链法)和开放地址法,但是相对来说链地址法的效率是要好于开放地址法的,所以等会在用 js 封装哈希表的时候,我们采用的也是链地址法。

三、哈希函数的实现

四、封装哈希表

1、创建哈希表

2、插入&修改数据

 3、获取方法

4、删除方法

5、其他方法

6、测试哈希表

7、完整代码

五、哈希表的扩容

1、哈希表的扩容思想

 2、哈希表的扩容实现

 下面修改插入&修改方法,如果添加东西太多,实现扩容

下面修改删除方法,如果删除东西太多,实现减容

六、实现容量恒为质数

下面是所有完善之后的代码


一、什么是哈希表

下面是 chatGPT 给出的解释:

哈希表(Hash Table)又称为散列表,是一种用于存储键值对的数据结构。它通过哈希函数将键映射到一个固定大小的数组中的位置,该位置称为哈希桶(Hash Bucket)。哈希表的优势在于可以快速插入、删除和查找数据。

哈希函数是哈希表的核心,它接受一个任意大小的输入(键),并通过计算返回一个固定大小的哈希值。哈希值被用作数组的索引,用于存储和检索对应的键值对。由于哈希函数的输出是固定的,不同的键可能会映射到相同的哈希值,这就产生了哈希冲突。

解决哈希冲突的一种常见方法是使用链表或其他数据结构来存储哈希冲突的键值对。当多个键被映射到同一个哈希桶时,它们会被链接在一起形成一个链表(或其他数据结构),并存储在同一个桶内。这样,当查找键值对时,可以先通过哈希函数找到对应的桶,然后在桶内顺序查找或通过进一步的数据结构快速查找目标键值对。

哈希表在平均情况下具有非常高效的插入、删除和查找操作。在理想情况下,哈希函数能够将键均匀地映射到不同的桶,从而实现常数时间复杂度的操作。然而,在某些情况下,哈希冲突可能会导致性能下降,甚至出现较差的情况。因此,在设计哈希函数时需要考虑均匀性和避免冲突的因素。

虽然文字有点多,但是讲的还是很好理解的。

下面是PPT中的讲解

 想要学习哈希表,那就不得不了解一些哈希表的概念

 二、哈希化时产生的问题:冲突 

注意:常见解决冲突的方法有两种,链地址法(拉链法)和开放地址法,但是相对来说链地址法的效率是要好于开放地址法的,所以等会在用 js 封装哈希表的时候,我们采用的也是链地址法。

三、哈希函数的实现

// 设计哈希函数
// 1 -> 将字符串转换成比较大的数字:hashCode
// 2 -> 将大的数字 hashCode 压缩到数组的范围之内
function hashFunc(str, size) {
    // 1、定义hashCode变量
    var hashCode = 0
    // 2、霍纳算法,用来计算hashCode的值
    // cats -> Unicode 编码
    for (var i = 0; i < str.length; i++) {
        // 一般选用 37 为那个质数 ,然后得到一个比较大的数字
        hashCode = 37 * hashCode + str.charCodeAt(i)
    }
    // 3、取余操作,得到压缩到数组范围内的数字
    var index = hashCode % size
    return index
}
console.log(hashFunc("abc", 7));

四、封装哈希表

1、创建哈希表

// 封装哈希表类
function HashTable() {
    // 属性
    this.storage = []
    this.count = 0
    this.limit = 7

    // 方法
    // 哈希函数的封装
    function hashFunc(str, size) {
        // 1、定义hashCode变量
        var hashCode = 0
        // 2、霍纳算法,用来计算hashCode的值
        // cats -> Unicode 编码
        for (var i = 0; i < str.length; i++) {
            // 一般选用 37 为那个质数 ,然后得到一个比较大的数字
            hashCode = 37 * hashCode + str.charCodeAt(i)
        }
        // 3、取余操作,得到压缩到数组范围内的数字
        var index = hashCode % size
        return index
    }
}

2、插入&修改数据

// 插入 & 修改操作的封装
HashTable.prototype.put = function(key, value) {
    // 1、根据 key 获取对应的 index
    var index = this.hashFunc(key, this.limit)

    // 2、根据 index 取出对应的 bucket
    var bucket = this.storage[index]

    // 3、判断该 bucket 是否为 null 
    if (bucket == null) {
        bucket = []
        this.storage[index] = bucket
    }

    // 4、判断是否是修改数据
    for (var i = 0; i < bucket.length; i++) {
        var tuple = bucket[i]
        if (tuple[0] == key) {
            tuple[1] = value
            return
        }
    }
    // 5、进行添加操作
    bucket.push([key, value])
}

 3、获取方法

// 获取操作的封装
HashTable.prototype.get = function(key) {
    // 1、根据 key 获取对应的 index 
    var index = this.hashFunc(key, this.limit)

    // 2、根据 index 取出对应的 bucket
    var bucket = this.storage[index]

    // 3、判断该 bucket 是否为 null
    if (bucket == null) {
        return null
    }

    // 4、如果有 bucket ,那么就进行线性查找
    for (var i = 0; i < bucket.length; i++) {
        var tuple = bucket[i]
        if (tuple[0] == key) {
            return tuple[1]
        }
    }

    // 5、依然没有找到,那么返回 null
    return null
}

4、删除方法

// 删除操作的封装
HashTable.prototype.remove = function(key) {
    // 1、根据 key 获取对应的 index
    var index = this.hashFunc(key, this.limit)

    // 2、根据 index 取出对应的 bucket 
    var bucket = this.storage[index]

    // 3、判断 bucket 是否为 null 
    if (bucket == null) {
        return null
    }

    // 4、如果有 bucket ,那么就进行线性查找,并且删除
    for (var i = 0; i < bucket.length; i++) {
        var tuple = bucket[i]
        if (tuple[0] == key) {
            bucket.splice(i, 1)
            this.count--
            return tuple[1]
        }
    }

    // 5、如果依然没有找到,那么返回 null
    return null
}

5、其他方法

// 封装其他方法
// 判断哈希表是否为 null 的封装
HashTable.prototype.isEmpty = function() {
    return this.count == 0
}

// 获取哈希表中元素个数的封装
HashTable.prototype.size = function() {
    return this.count
}

6、测试哈希表

// 测试哈希表
// 1、创建哈希表
var ht = new HashTable()

// 2、插入数据
ht.put("abc", "哈哈哈")
ht.put("cba", "啦啦啦")

// 3、获取数据
console.log(ht.get("abc"));  // 哈哈哈

// 4、修改方法
ht.put("abc", "哈哈哈哈哈")
console.log(ht.get("abc"));  // 哈哈哈哈哈

// 5、删除方法
ht.remove("abc")
console.log(ht.get("abc"));  // null

// 6、判断是否为空
console.log(ht.isEmpty());  // false

// 7、查看哈希表中元素的个数
console.log(ht.size());  // 1

7、完整代码

// 封装哈希表类
function HashTable() {
    // 属性
    this.storage = []
    this.count = 0
    this.limit = 7

    // 方法
    // 哈希函数的封装
    HashTable.prototype.hashFunc = function(str, size) {
        // 1、定义hashCode变量
        var hashCode = 0
        // 2、霍纳算法,用来计算hashCode的值
        // cats -> Unicode 编码
        for (var i = 0; i < str.length; i++) {
            // 一般选用 37 为那个质数 ,然后得到一个比较大的数字
            hashCode = 37 * hashCode + str.charCodeAt(i)
        }
        // 3、取余操作,得到压缩到数组范围内的数字
        var index = hashCode % size

        return index
    }

    // 插入 & 修改操作的封装
    HashTable.prototype.put = function(key, value) {
        // 1、根据 key 获取对应的 index
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket
        var bucket = this.storage[index]

        // 3、判断该 bucket 是否为 null 
        if (bucket == null) {
            bucket = []
            this.storage[index] = bucket
        }

        // 4、判断是否是修改数据
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                tuple[1] = value
                return
            }
        }
        // 5、进行添加操作
        bucket.push([key, value])
        this.count += 1
    }

    // 获取操作的封装
    HashTable.prototype.get = function(key) {
        // 1、根据 key 获取对应的 index 
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket
        var bucket = this.storage[index]

        // 3、判断该 bucket 是否为 null
        if (bucket == null) {
            return null
        }

        // 4、如果有 bucket ,那么就进行线性查找
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                return tuple[1]
            }
        }

        // 5、依然没有找到,那么返回 null
        return null
    }

    // 删除操作的封装
    HashTable.prototype.remove = function(key) {
        // 1、根据 key 获取对应的 index
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket 
        var bucket = this.storage[index]

        // 3、判断 bucket 是否为 null 
        if (bucket == null) {
            return null
        }

        // 4、如果有 bucket ,那么就进行线性查找,并且删除
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                bucket.splice(i, 1)
                this.count--
                return tuple[1]
            }
        }

        // 5、如果依然没有找到,那么返回 null
        return null
    }

    // 封装其他方法
    // 判断哈希表是否为 null 的封装
    HashTable.prototype.isEmpty = function() {
        return this.count == 0
    }

    // 获取哈希表中元素个数的封装
    HashTable.prototype.size = function() {
        return this.count
    }
}

// 测试哈希表
// 1、创建哈希表
var ht = new HashTable()

// 2、插入数据
ht.put("abc", "哈哈哈")
ht.put("cba", "啦啦啦")

// 3、获取数据
console.log(ht.get("abc"));

// 4、修改方法
ht.put("abc", "哈哈哈哈哈")
console.log(ht.get("abc"));

// 5、删除方法
ht.remove("abc")
console.log(ht.get("abc"));

// 6、判断是否为空
console.log(ht.isEmpty());

// 7、查看哈希表中元素的个数
console.log(ht.size());

五、哈希表的扩容

1、哈希表的扩容思想

 2、哈希表的扩容实现

// 哈希表扩容/缩容封装
HashTable.prototype.resize = function(newLimit) {
    // 保存旧的数组内容
    var oldStorage = this.storage

    // 2、重置所有的属性
    this.storage = []
    this.conut = 0
    this.limit = newLimit

    // 3、遍历 oldStorage 中所有的 bucket
    for (var i = 0; i < oldStorage.length; i++) {
        // 3.1 取出对应的 bucket 
        var bucket = oldStorage[i]

        // 3.2 判断 bucket 是否为 null
        if (bucket == null) {
            continue
        }

        // 3.3 bucket 中有数据,那么取出数据,重新插入
        for (var j = 0; j < bucket.length; j++) {
            var tuple = bucket[j]
            this.put(tuple[0], tuple[1])
        }
    }
}

 下面修改插入&修改方法,如果添加东西太多,实现扩容

// 修改插入&修改方法,如果添加东西太多,实现扩容
// 插入 & 修改操作的封装
HashTable.prototype.put = function(key, value) {
    // 1、根据 key 获取对应的 index
    var index = this.hashFunc(key, this.limit)

    // 2、根据 index 取出对应的 bucket
    var bucket = this.storage[index]

    // 3、判断该 bucket 是否为 null 
    if (bucket == null) {
        bucket = []
        this.storage[index] = bucket
    }

    // 4、判断是否是修改数据
    for (var i = 0; i < bucket.length; i++) {
        var tuple = bucket[i]
        if (tuple[0] == key) {
            tuple[1] = value
            return
        }
    }
    // 5、进行添加操作
    bucket.push([key, value])
    this.count += 1

    // 6、判断是否需要扩容操作
    if (this.count > this.limit * 0.75) {
        this.resize(this.limit * 2)
    }
}

下面修改删除方法,如果删除东西太多,实现减容

// 修改删除方法,如果删除东西太多,实现减容
// 删除操作的封装
HashTable.prototype.remove = function(key) {
    // 1、根据 key 获取对应的 index
    var index = this.hashFunc(key, this.limit)

    // 2、根据 index 取出对应的 bucket 
    var bucket = this.storage[index]

    // 3、判断 bucket 是否为 null 
    if (bucket == null) {
        return null
    }
    // 4、如果有 bucket ,那么就进行线性查找,并且删除
    for (var i = 0; i < bucket.length; i++) {
        var tuple = bucket[i]
        if (tuple[0] == key) {
            bucket.splice(i, 1)
            this.count--
            return tuple[1]

            // 缩小容量
            if (this.limit > 7 && this.count < this.limit * 0.25) {
                // Math.floor 向下取整
                this.resize(Math.floor(this.limit / 2))
            }
        }
    }
    // 5、如果依然没有找到,那么返回 null
    return null
}

六、实现容量恒为质数

// 封装判断某个数字是否是质数
HashTable.prototype.isPrime = function(num) {
    // 1、获取 num 的平方根
    var temp = parseInt(Math.sqrt(num))

    // 2、循环判断
    for (var i = 2; i <= temp; i++) {
        if (num % i == 0) {
            return false
        }
    }
    return true
}

// 封装获取质数的方法
HashTable.prototype.getPrime = function(num) {
    // 循环判断这个数是否为质数,如果不是质数,就一直加一,什么时候是质数就返回这个数
    while (!this.isPrime(num)) {
        num++
    }
    return num
}

下面是所有完善之后的代码

// 封装哈希表类
function HashTable() {
    // 属性
    this.storage = []
    this.count = 0
    this.limit = 7

    // 方法
    // 哈希函数的封装
    HashTable.prototype.hashFunc = function(str, size) {
        // 1、定义hashCode变量
        var hashCode = 0
        // 2、霍纳算法,用来计算hashCode的值
        // cats -> Unicode 编码
        for (var i = 0; i < str.length; i++) {
            // 一般选用 37 为那个质数 ,然后得到一个比较大的数字
            hashCode = 37 * hashCode + str.charCodeAt(i)
        }
        // 3、取余操作,得到压缩到数组范围内的数字
        var index = hashCode % size

        return index
    }

    // 插入 & 修改操作的封装
    HashTable.prototype.put = function(key, value) {
        // 1、根据 key 获取对应的 index
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket
        var bucket = this.storage[index]

        // 3、判断该 bucket 是否为 null 
        if (bucket == null) {
            bucket = []
            this.storage[index] = bucket
        }

        // 4、判断是否是修改数据
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                tuple[1] = value
                return
            }
        }
        // 5、进行添加操作
        bucket.push([key, value])
        this.count += 1

        // 6、判断是否需要扩容操作
        if (this.count > this.limit * 0.75) {
            var newSize = this.limit * 2
            var newPrime = this.getPrime(newSize)
            this.resize(newPrime)
        }
    }

    // 获取操作的封装
    HashTable.prototype.get = function(key) {
        // 1、根据 key 获取对应的 index 
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket
        var bucket = this.storage[index]

        // 3、判断该 bucket 是否为 null
        if (bucket == null) {
            return null
        }

        // 4、如果有 bucket ,那么就进行线性查找
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                return tuple[1]
            }
        }

        // 5、依然没有找到,那么返回 null
        return null
    }

    // 删除操作的封装
    HashTable.prototype.remove = function(key) {
        // 1、根据 key 获取对应的 index
        var index = this.hashFunc(key, this.limit)

        // 2、根据 index 取出对应的 bucket 
        var bucket = this.storage[index]

        // 3、判断 bucket 是否为 null 
        if (bucket == null) {
            return null
        }

        // 4、如果有 bucket ,那么就进行线性查找,并且删除
        for (var i = 0; i < bucket.length; i++) {
            var tuple = bucket[i]
            if (tuple[0] == key) {
                bucket.splice(i, 1)
                this.count--
                return tuple[1]

                // 缩小容量
                if (this.limit > 7 && this.count < this.limit * 0.25) {
                    // Math.floor 向下取整
                    var newSize = Math.floor(this.limit / 2)
                    var newPrime = this.getPrime(newSize)
                    this.resize(newPrime)
                }
            }
        }

        // 5、如果依然没有找到,那么返回 null
        return null
    }

    // 封装其他方法
    // 判断哈希表是否为 null 的封装
    HashTable.prototype.isEmpty = function() {
        return this.count == 0
    }

    // 获取哈希表中元素个数的封装
    HashTable.prototype.size = function() {
        return this.count
    }

    // 哈希表扩容/缩容封装
    HashTable.prototype.resize = function(newLimit) {
        // 保存旧的数组内容
        var oldStorage = this.storage

        // 2、重置所有的属性
        this.storage = []
        this.conut = 0
        this.limit = newLimit

        // 3、遍历 oldStorage 中所有的 bucket
        for (var i = 0; i < oldStorage.length; i++) {
            // 3.1 取出对应的 bucket 
            var bucket = oldStorage[i]

            // 3.2 判断 bucket 是否为 null
            if (bucket == null) {
                continue
            }

            // 3.3 bucket 中有数据,那么取出数据,重新插入
            for (var j = 0; j < bucket.length; j++) {
                var tuple = bucket[j]
                this.put(tuple[0], tuple[1])
            }
        }
    }

    // 封装判断某个数字是否是质数
    HashTable.prototype.isPrime = function(num) {
        // 1、获取 num 的平方根
        var temp = parseInt(Math.sqrt(num))

        // 2、循环判断
        for (var i = 2; i <= temp; i++) {
            if (num % i == 0) {
                return false
            }
        }
        return true
    }

    // 封装获取质数的方法
    HashTable.prototype.getPrime = function(num) {
        // 循环判断这个数是否为质数,如果不是质数,就一直加一,什么时候是质数就返回这个数
        while (!this.isPrime(num)) {
            num++
        }
        return num
    }
}

// 测试哈希表
// 1、创建哈希表
var ht = new HashTable()

// 2、插入数据
ht.put("abc", "哈哈哈")
ht.put("cba", "啦啦啦")

// 3、获取数据
console.log(ht.get("abc"));

// 4、修改方法
ht.put("abc", "哈哈哈哈哈")
console.log(ht.get("abc"));

// 5、删除方法
ht.remove("abc")
console.log(ht.get("abc"));

// 6、判断是否为空
console.log(ht.isEmpty());

// 7、查看哈希表中元素的个数
console.log(ht.size());

下面附上b站视频链接,需要学习的可以去看看(JavaScript算法与数据结构),如果光看文章可能还是有点晦涩难懂,但是看老师视频的讲解,基本就能掌握了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

哈希表以及用js封装一个哈希表 的相关文章

  • 在 Web 浏览器中查找触发 then 事件的 jQuery 代码

    我加入了一个团队来从事一个项目 现在他们使用 jQuery 并且很多 javascript 文件都是外部文件而不是嵌入的 当我点击一个按钮时 它看起来就像 a class button cancel Cancel a 它触发一个在一个 ja
  • Typescript:按值检查对象是否存在于数组中

    我有这个数据 roles roleId 69801 role ADMIN roleId 69806 role SUPER ADMIN roleId 69805 role RB roleId 69804 role PILOTE roleId
  • 无法显示由 Fine-uploader 上传到 Amazon s3 的图像

    我现在尝试设置fineuploader s3以显示在aws服务器上成功上传的文件的图像 如示例页面上所做的那样 http fineuploader com s3 demo http fineuploader com s3 demo 我 仍然
  • Twisted 的 Deferred 和 JavaScript 中的 Promise 一样吗?

    我开始在一个需要异步编程的项目中使用 Twisted 并且文档非常好 所以我的问题是 Twisted 中的 Deferred 与 Javascript 中的 Promise 相同吗 如果不是 有什么区别 你的问题的答案是Yes and No
  • 如何通过 HTML 按钮播放声音

    我目前通过网站播放音乐的方法是通过 HTML 音频标签 不过我希望能够通过 HTML 按钮来播放它 该按钮应该能够在播放和停止之间切换音乐 我在 JSFiddle 创建了一个示例 但不知道如何实现它 有人可以告诉我如何使用我的 JSFidd
  • 禁用 JavaScript 中的右键单击

    当我尝试禁用右键单击时 它不起作用 我尝试使用下面的代码 document onclick function e console log e button if e button 2 e preventDefault return fals
  • 响应式网格布局框架[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • 如何使用 jQuery 向表中添加新行,并为其分配递增的 id

    我有一个现有的 HTML 表格 它是用户输入 GPS 点的表单的一部分 用户还可以选择上传 GPS 数据点 我想要一个用户可以按下的按钮 其中一些 Javascript 会向表中添加一个或多个新行 但新行必须继续增加表中使用的名称和 id
  • 使react-leaflet能够离线使用

    我一直在使用反应传单 https github com PaulLeCam react leaflet图书馆 到目前为止运作良好 现在我希望网站预加载尽可能多的图块 以便网络应用程序 也是 PWA 可以在没有互联网的情况下使用 我找到了一些
  • KeyboardEvent.keyCode 已弃用。这在实践中意味着什么?

    根据 MDN 我们绝对应该not正在使用 keyCode财产 它已被弃用 https developer mozilla org en US docs Web API KeyboardEvent keyCode https develope
  • 使用 jquery 将字符串数组转换为整数

    我正在尝试将 jquery 中的字符串数组转换为整数数组 这是我的尝试 var cdata data values split each cdata function i l l parseInt l 我认为在这种情况下你不需要使用 Jqu
  • 如何滚动到div内的元素?

    我有一个滚动的div我想在点击它时发生一个事件 它会强制执行此操作div滚动以查看内部元素 我写的JavasCript是这样的 document getElementById chr scrollIntoView true 但这会在滚动时滚
  • 是否可以使用打字稿映射类型来创建接口的非函数属性类型?

    所以我正在研究 Typescript 的映射类型 是否可以创建一个接口来包装另一种类型 从而从原始类型中删除函数 例如 interface Person name string age number speak void type Data
  • 如何在 e2e AngularJS 测试中进行文件上传?

    在我的一种观点中 我有一个文件上传控件 它支持通过拖放或单击按钮后打开的标准文件对话框上传文件 How to do this in my e2e tests1 1 Just one of the two options will be en
  • Jquery,清除/清空 tbody 元素的所有内容?

    我认为这会相当简单 但似乎空方法无法清除我拥有的 tbody 如果有人知道执行此操作的正确方法 我将不胜感激 我只想删除 tbody 中包含的所有内容 到目前为止我正在尝试 tbodyid empty HTML table tbody tr
  • 我可以使用 jQuery 动态创建文件(及其内容)吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 这是我的 HTML 代码 ul li
  • 如何更改订阅值?使用 rxJS

    我正在创建一个计时器 需要你的帮助 我刚刚学习 Angular 和 rxJS 对此我有一些疑问 我正在创建一个具有启动 停止 暂停 重置功能的计时器 并且 btn Reset 必须将我的计时器 暂停 到 300 毫秒 怎么做 D 我的启动定
  • Bootstrap 3 / 显示模式不适用于 javascript 方式

    我用Modal http getbootstrap com javascript modalsBootstrap 3 0 的功能 我有这个代码 a href myNestedContent Open the modal containing
  • 如何调试 Gulp 任务?

    如何调试我的中定义的 gulp 任务gulpfile js使用诸如 Google Chrome 调试器之类的调试器逐行单步执行任务的代码 对于 Node js 6 3 版本 您可以使用 inspect flag https nodejs o

随机推荐

  • Oracle报错ORA-00911: 无效字符问题

    跑kettle任务 今天写sql查询数据库数据时出现ORA 00911 无效字符问题 我把SQL到toad中是可以查询到数据的 但是在MyECLIPSE中执行就报ORA 00911 无效字符的错误 原因 SQL中 有个 分号 里面多了一个
  • Mac 安装 Neo4j

    1 下载Neo4j 社区版 MacOS安装社区版Neo4j 图数据库 https blog csdn net huacha article details 81123410 问题 在下载JDK时需要Oracle 登陆账号 解决方法 http
  • Vue+ElementUI实现简单的用户管理系统(四):查看用户详情页及删除用户

    一 展示用户详细信息 在点击 查看 按钮时 传递了用户的Id 我们要把这个Id拿出来 this route query id created this handle this route query id handle方法 也就是根据id使
  • [YOLO专题-3]:总体-目标检测的常见模型评估指标

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122134907 目录 前言
  • HTML BFC的理解与作用

    HTML BFC的理解与作用 含义 BFC Block formatting context 直译为 块级格式化上下文 它是一个独立的渲染区域 只有Block level box参与 它规定了内部的Block level Box如何布局 并
  • elasticsearch实现入库分词,查询不分词,实现like关键字%

    因为在工作中遇到一个需求 需要对请求内容实现类似于mysql的 like 关键字 模糊匹配功能 同时要保证效率大数据量效率问题 因此不能使用wildcard在网上看了很多也不太好使 自己琢磨了一下成功了 该功能仅对非中文存储的字段有效果 使
  • Blender软硬边

    https www youtube com watch v CdHXpHPWKYo blender这里的算法感觉就是根据角度做自动平滑 然后mark sharp它就不平滑 貌似有bug 加修改器貌似可以解决这个问题 凹面貌似也有点问题 设置
  • 结合Android Studio和MAT检测并简单分析内存泄露

    1 什么是GC 在分析内存泄露之前首先要了解一下GC GC Garbage Collection 就是Java中常提到的垃圾回收 指的是JVM会自动回收不在被引用的内存数据 2 什么是GC Roots GC Roots即Java虚拟机当前存
  • SAP-基于批次特定计量单位的应用-01-产品数量管理

    原文链接 https mp weixin qq com s zknWGuz2lU387vAGSiykw 大家可以关注我个人公众号 所有分享内容 会在公众号第一时间推送 且阅读排版更好 愿大家的学习 轻松且愉快 如果大家觉得有用 希望转发关注
  • 计算机打字正确姿势,电脑打字手指的正确姿势,涨知识了

    近年来 随着科技水平的提高 电脑已经成为了必不可少的工具了 能够为工作和学习提供一定的便利性 今天来给大家说说在电脑上打字手指应如何摆放 以帮助提高打字的速度 熟悉键盘 01 在开始打字前 首先要对键盘上每个字母对应的位置有一定的了解 不仅
  • LeGO-LOAM代码详细注释版

    学习LeGO LOAM时 写的代码注释github代码链接 一部分注释来自github用户wykxwyc 一部分来自网上查阅 还有一部分是自己的理解 持续更新中
  • C语言---离散数学实验--图的基本概念及其应用

    目录 欧拉图的判定 实验内容 编辑 无向图的判断 算法展示 源码 有向图的判断 算法展示 源码 求欧拉路 算法展示 整体源码 对无向图的判断 对有向图的判断 二叉树的应用 源码 源码下载 实验目的 掌握判断欧拉图的方法 掌握求最优二叉树的方
  • kubeadm常用

    kubeadm常用 配置kubeadm自动补全 初始化一个master节点 导出kubeadm默认配置文件 将node节点加入集群 生成node配置 升级k8s版本 kubeadm升级node 维护或下线node节点 管理kubeadm j
  • 1-2 VS2019常用调试方法(断点设置、条件断点、调试按钮、逐过程、逐语句、监视变量、快速监视)

    文章目录 前言 1 打印数据 2 普通断点 2 1断点快捷键 3 条件断点与条件追踪 4 单步调试 5 添加监视 5 1快速监视 前言 主要调试方法 1 打印数据 2 普通断点 3 条件断点与条件追踪 4 单步调试 5 添加监视 1 打印数
  • JavaWeb自我学习——Request(请求)

    目录 Request 1 继承体系 2 获取请求数据 通用方式获取请求参数 idea模板创建servlet 请求参数中文乱码处理 Tomcat 8 0之后 已将GET请求乱码问题解决 设置默认的解码方式为UTF 8 3 请求转发 请求转发资
  • 中小企业在数字化转型上所面对的问题都有哪些?_光点科技

    随着科技的飞速发展 数字化转型已经成为企业持续发展的必由之路 尤其是中小企业 数字化转型不仅可以提高效率 降低成本 还可以拓展市场 增强竞争力 然而 数字化转型并非一帆风顺 中小企业在这个过程中面临着一系列挑战和问题 1 资金问题 中小企业
  • fb设备驱动1:fb设备的显像原理和步骤

    lcd的显像原理 将DDR内存的一部分划分出来作为显存 显存与lcd显示屏幕之间做一个双向的映射 然后用户只需要将需要显示的内容放入显存之中 然后显存中的内容就会刷新到lcd的储存器中进行显示 显存 在内核之中申请一块内存作为显存 由于内核
  • #ifndef/#define/#endif使用详解

    想必很多人都看过 头文件中的 ifndef define endif 防止该头文件被重复引用 但是是否能理解 被重复引用 是什么意思 是不能在不同的两个文件中使用include来包含这个头文件吗 如果头文件被重复引用了 会产生什么后果 是不
  • spring之AOP总结

    AOP Aspect Oriented Programming 面向切面编程 指在程序运行期间 将某段代码动态的切入到指定方法的指定位置进行运行的这种编程方法 面向切面编程 专业术语 连接点 即指定位置 spring允许你使用通知的地方 每
  • 哈希表以及用js封装一个哈希表

    最近在学数据结构和算法 正好将学习的东西记录下来 我是跟着一个b站博主学习的 是使用js来进行讲解的 待会也会在文章后面附上视频链接地址 大家想学习的可以去看看 本文主要讲解哈希表 其他数据结构后续学完也会持续更新 目录 一 什么是哈希表