二分法,不止是算法 - 你可能不知道的二分法应用

简介: 二分法大家都知道,记得应该是从初中学数学就学过,而在编程中也经常使用二分法来进行有序数列的查找。然而二分法并不紧紧局限于算法中的使用,他还被广泛使用于我们的工具中、数学中甚至生活中。

网络异常,图片无法展示
|

二分法大家都知道,记得应该是从初中学数学就学过,而在编程中也经常使用二分法来进行有序数列的查找。

然而二分法并不紧紧局限于算法中的使用,他还被广泛使用于我们的工具中、数学中甚至生活中。

算法应用

算法中会使用二分法进行查找,然后使用两个索引来代表目标数据所可能在的范围,然后将数组从中间进行拆分,拿到中间数进行比对,即可根据数组的排序顺序、目标元素和中间数的大小比较,得出更小的比对区间,从而一次次缩小查找范围,在面对大数据时,可以有效的减少查找时间,提升查找效率,将事件复杂度缩小到 O(log2(n))。不过二分法也存在一定局限性,必须要数组是有序的。

可以大概看一下实现,一段平平无奇的二分查找代码:

export const binarySearch = (arr: number[], target: number): number => {
    const len = arr.length;
    if (!len) return -1;
    let startIndex = 0;
    let endIndex = len - 1;
    while (startIndex <= endIndex) {
        let midIndex = ((startIndex + endIndex) / 2) | 0;
        let midTarget = arr[midIndex];
        if (target === midTarget) return;
        target < midTarget ? (endIndex = midIndex - 1) : (startIndex = midIndex + 1);
    }
    return -1;
};
复制代码

当然,上面只是顺带提过,并非本文的重点,下面说下二分法在非算法领域的应用,看看它的应用之广泛,可能超乎你的想象。

Git 中的二分法

git 中就存在二分法的另一种应用:git bisect。当我们代码上线后突然有一天一个最近根本没改动的模块出现问题了,一般会很难定位问题是由哪次改动引起的。这是便可以使用 git bisect 进行帮助定位。要启动我们一般会指定一个起点 hash,终点一般就是当前 HEAD。

git bisect start HEAD HEAD~10
复制代码

git 会切换到 HEAD~10 的 commit 上,此时你可以查看当前版本是否存在该 bug,然后根据存在结果判定输入 git bisect goodgit bisect bad。git 便会自动在 bad 范围中进行二分,缩小查找范围,直到最终确定最先出现 bug 的 commit:a819d21 is the first bad commit

借助 git bisect 可以在 bug 不明确时快速定位到初次导致 bug 的 commit,便可借助当次 commit 中的修改,快速定位到引起 bug 的原因。

VSCode 中的二分法

而在 VSCode 中,二分法也同样有着类似的用途。VSCode 作为一代轻量级 IDE 新秀,虽然功能已经非常丰富,但是对比一些专业的 IDE 在很多功能上还是有所欠缺。所以开发者都会使用大量插件来弥补这些功能。然而插件五花八门,质量参差不齐,很容易就会出现一些插件导致内存泄漏、CPU 爆满的情况。所以在这种情况下就需要一个个禁用插件来排查到底是什么插件导致的问题。于是乎 VSCode 中也出现了自带的二分法定位问题插件的功能。

要启动该功能,只需要启动 VSCode 命令输入 Extension Bisect,也可在插件菜单中启动。

网络异常,图片无法展示
|

启动后 VSCode 提示本次可能需要的次数等说明,确定后便会将插件进行拆分禁用,然后在右下角询问当前情况是否正常(可能需要手动点击右下角消息提示打开)。

网络异常,图片无法展示
|

从而一次次缩小范围,定位到引起问题的插件。

网络异常,图片无法展示
|

除了定位插件的 bug,你也可以借助它来定位插件的功能,比如你很好奇某个 snippet 是哪个插件提供的,同样可以借助它来定位。

BUG 定位中的二分法

除了上述工具自带的这些应用了二分法的工具,我们在实际编程过程中同样可以借助二分法来定位 bug。

通常修 bug 时最难的不是改代码,而是定位代码。首先必须要知道导致 bug 的代码位置才能修复它。所以日常遇到 bug 却毫无头绪时,二分法可以非常无脑的帮你缩小需要排查的范围。

除了上面的 git bisect,我通常还会通过代码分割来进行代码定位,比如一个页面上有多个模块,此时便可将模块进行去除,然后查看 bug 是否消除来不断判定缩小查找范围,从而最终定位。又比如页面中的样式出现无法理解的情况,也可以通过将生效的样式、嵌套位置等进行二分来进行原因定位。

生活中的二分法

除了上述在编程中的二分法使用,我们在生活中也可以使用二分法来解决问题。

比如发布文字到网上遇到 SC,死活通不过而自己又找不到失败的原因,就可以使用二分法分段尝试定位。比如数据上传过大,又不知道上传多大的数据包合适,可以通过二分法尝试出合适的大小。比如和小朋友玩游戏,抽一张扑克牌、或写一个数字,然后看看谁能更快的猜到数字是多少。比如一些有意思的数学题,100 个看起来一样的球里有一个重量比其它的重,有一个天平如何快速的找出不同的那颗球。

总结

二分法是一种很常见的方法,他的本质是通过判定查找目标是否在某个范围内,然后不断对范围进行拆分定位,从而进行批量的筛除,达成查找的目的。只要在能够判定目标范围的情况下,二分法都能发挥出不错的效果。除了二分法,还可以使用三分法等其它衍生的方案,其本质是想通的。如果大家还知道哪些关于二分法的使用案例,欢迎留言。

在生活中同样可以使用二分法,不过在专业领域个人觉得还是要以思考为优先,能够直接动脑的就不要"动手",毕竟二分法就是一种试错法(比依次试错好一丢丢的那种),产生依赖很容易丢失自己的思考能力。🤦‍♂️ 在一些非专业领域,或者丧失思考能力的情况下还是很推荐的。🐶

相关文章
|
12天前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
30 3
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的优化算法及其应用
【10月更文挑战第8天】 本文将探讨深度学习中常用的优化算法,包括梯度下降法、Adam和RMSProp等,介绍这些算法的基本原理与应用场景。通过实例分析,帮助读者更好地理解和应用这些优化算法,提高深度学习模型的训练效率与性能。
113 63
|
6天前
|
存储 算法 搜索推荐
这些算法在实际应用中有哪些具体案例呢
【10月更文挑战第19天】这些算法在实际应用中有哪些具体案例呢
15 1
|
12天前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
46 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
21天前
|
算法 安全 物联网
如何应用SM2算法进行身份认证
【10月更文挑战第5天】如何应用SM2算法进行身份认证
28 1
|
21天前
|
存储 算法 安全
SM2算法的应用场景有哪些?
【10月更文挑战第5天】SM2算法的应用场景有哪些?
37 1
|
24天前
|
存储 算法 安全
Python 加密算法详解与应用
Python 加密算法详解与应用
14 1
|
26天前
|
机器学习/深度学习 算法
深度学习中的优化算法及其应用
本文探讨了深度学习中常用的优化算法,包括梯度下降、随机梯度下降、动量方法和Adam方法。通过对比这些算法的优缺点及适用场景,帮助读者更好地理解和应用这些优化方法。
23 2
|
6天前
|
监控 算法 数据挖掘
HyperLogLog算法有哪些应用场景呢
【10月更文挑战第19天】HyperLogLog算法有哪些应用场景呢
8 0
|
12天前
|
机器学习/深度学习 算法 数据建模
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
计算机前沿技术-人工智能算法-生成对抗网络-算法原理及应用实践
18 0