V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
1oNflow
V2EX  ›  Java

递归结束的判断条件写==和>=有区别吗

  •  
  •   1oNflow · 2020-03-23 15:41:17 +08:00 · 3100 次点击
    这是一个创建于 1699 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如判断递归深度是否到达某个值,应该用

    if (depth == K) return;
    

    因为逻辑上肯定会先到达 K,而不会超过 K

    dfs(depth+1);
    

    但是写成

    if (depth >= K) return;
    

    会不会更加缜密(避免意外情况)?

    另外 JVM 处理==和>=/<=的判断效率上会有区别吗?

    27 条回复    2020-03-24 16:52:10 +08:00
    Jooooooooo
        1
    Jooooooooo  
       2020-03-23 15:42:38 +08:00
    jvm 不会在这种东西上有区别的 (那也太笨了吧
    mooyo
        2
    mooyo  
       2020-03-23 15:43:58 +08:00
    主要是为了防御性吧,万一其他地方写崩了,depth 没有到达 K 直接到了 K+1 或者 K+2,就完蛋了。
    wysnylc
        3
    wysnylc  
       2020-03-23 15:46:49 +08:00
    就算有,你也要写>=
    Dvel
        4
    Dvel  
       2020-03-23 15:53:42 +08:00   ❤️ 1
    可能会遭遇高能粒子的冲击,太空辐射导致的 bit 翻转,三体质子的科技锁定,导致永远不会出现 K 。
    Jirajine
        5
    Jirajine  
       2020-03-23 15:55:18 +08:00 via Android
    优先用==和!=吧,因为可能有些类型没有实现大于或小于运算符。
    spicecch
        6
    spicecch  
       2020-03-23 15:56:36 +08:00
    @Dvel 一看就是老三体迷了
    fffang
        7
    fffang  
       2020-03-23 16:05:35 +08:00
    突然想到这个,大家看看有没有共通性。

    `
    if (oneCondition) {
    } else if (anotherCondition) {
    }
    `

    `
    if (oneCondition) {
    } else {
    }
    `

    两种判断没有除了 oneCondition 和 anotherCondition 以外的情况。
    CismonX
        8
    CismonX  
       2020-03-23 16:06:19 +08:00   ❤️ 3
    拿 x86 为例,一般来说这些条件跳转的底层实现都是无外乎比较 ZF/OF/SF/CF 这几个 flag,比如 JZ 检查 ZF == 0,JGE 检查 SF == OF,实际的性能差异即使有也完全可以忽略不计。其他处理器上也是同理,楼主完全不必计较这种级别的性能问题。
    fancy111
        9
    fancy111  
       2020-03-23 16:10:11 +08:00
    逻辑就是逻辑,哪有什么区别。你要考虑的是什么情况下要区分开用。
    有什么意外情况? n=n+1 难道会跳过一个 1 吗? 。。。除非内存在瞬间被修改。
    m30102
        10
    m30102  
       2020-03-23 16:12:44 +08:00
    概率小于行星撞地球的事就可以不用考虑了。
    ilotuo
        11
    ilotuo  
       2020-03-23 16:17:06 +08:00
    这种问题有另类点的解决思路: 换个好一点的 ide. 有性能影响编译器会提醒你的
    BestSera
        12
    BestSera  
       2020-03-23 16:17:15 +08:00
    同意二楼说的,两种写法逻辑上都没问题,但个人还是倾向>=
    就像千年虫 bug,谁还没个万一呢
    ilotuo
        13
    ilotuo  
       2020-03-23 16:24:38 +08:00
    我错了...别回复我...
    autoxbc
        14
    autoxbc  
       2020-03-23 16:33:43 +08:00
    宇宙射线的扰动不要考虑么,不然要 ECC 内存做啥
    DOLLOR
        15
    DOLLOR  
       2020-03-23 16:43:33 +08:00
    当然是“>=”和“<=”了。万一未来逻辑修改了,不是+1 步进了,这样更容易发现问题。
    LANB0
        16
    LANB0  
       2020-03-23 17:00:33 +08:00
    @fancy111 缓冲区溢出或者多线程环境下也不是不可能出现内存值被瞬间修改的情况,>=显然更稳妥些。入行时,老师傅曾告诉我,你以为永远不会执行的 else 分支,一定会在某个特定条件下执行,然后送你一顶大锅。此处如 @fffang 所说,同理
    CodeEncryption
        17
    CodeEncryption  
       2020-03-23 17:10:48 +08:00
    逻辑没错就没有区别
    mightofcode
        18
    mightofcode  
       2020-03-23 17:21:17 +08:00
    没区别
    我有强迫症,喜欢写>=
    arthas2234
        19
    arthas2234  
       2020-03-23 17:29:02 +08:00
    >=容错率更高
    你对你自己写的代码有自信,但是要防备某些猪队友
    相信我,有些时候可以救命
    newtype0092
        20
    newtype0092  
       2020-03-23 17:38:33 +08:00
    @fffang 确实就是这个场景,一定是包含所有情况的代码比依赖某周确定情况(哪怕是+1 操作这种简单明了的)的代码更健壮。
    secondwtq
        21
    secondwtq  
       2020-03-23 22:38:48 +08:00
    ... 更严格的条件有利于发现潜在的问题
    更宽松的条件有利于养肥潜在的问题
    secondwtq
        22
    secondwtq  
       2020-03-23 22:39:36 +08:00   ❤️ 2
    楼主真要“缜密”的话就把 > k 的情况给 assert/unreachable 掉
    LokiSharp
        23
    LokiSharp  
       2020-03-24 07:58:06 +08:00 via iPhone
    如果歩长从 1 变成 2 了怎么办?
    alphatoad
        24
    alphatoad  
       2020-03-24 08:22:12 +08:00 via iPhone
    还真别说,宇宙粒子导致位元反转不少见
    jinliming2
        25
    jinliming2  
       2020-03-24 09:01:44 +08:00 via iPhone   ❤️ 1
    == 的话,没问题,>= 容错率更高,但容错意味着隐藏 Bug,所以在写代码特时候,用 >= 的时候也要思考,即使不正常地出现了 > 的情况,会不会对后续程序造成影响,如果会造成影响,一定要抛个异常。
    paoqi2048
        26
    paoqi2048  
       2020-03-24 10:43:55 +08:00
    世界线变动了
    songkeys
        27
    songkeys  
       2020-03-24 16:52:10 +08:00   ❤️ 1
    其实不考虑容错率,可以从另一个场景看来这个问题:

    A 的年龄是 B 的两倍加上 C 的年龄后再减去 B 的年龄,求 A 的年龄:

    a = 2b + c - b;

    这个代码的效果其实跟下面的是等价的:

    a = b + c;

    二者都没有错,但我更偏向于在代码中保留第一种写法,也就是更符合「直觉」、更有「含义」的写法。

    当然,这是个很简单的例子,所以你可能觉得很弱智。但碰到复杂的公式计算,我通常也都不会尽自己可能地去化简到极致来减少计算机的运算,而是保留符合直觉且有含义的写法,哪怕更复杂。

    回到你的例子。我在写迭代的时候,遇到 base case,也会根据题意去定义条件。比如,如果题目说「当超过 xx 时便不再……」,那么我就会把条件写成 >= 或者 <=;而如果题目说「直到它为 xx 时便不再」,那么我就会写成 == 或者 !=。

    再说回上面大家提到的容错率。如果你的代码真的符合题意背景,且它可以被证明是能达到 == 的条件的(请注意这个前提),便无需焦虑于使用一个 >= 来加以保护,甚至这么做会破坏了我刚刚所说的直觉和含义。如果你真的需要这一层防护的话,那么就是你写错了,请直接 debug,而不是靠这一层神秘防护来「修复」 bug 。

    当然……(老胡认为?)凡事没有一定,上面有很多建议是从工业代码、防备猪队友的角度出发,楼主如果已经处于工业代码的屎山中,完全无法做到缜密地顾全一切,那就大势所趋吧。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3055 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 00:15 · PVG 08:15 · LAX 16:15 · JFK 19:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.