【问题标题】:Java && || in RETURN statements?Java && ||在 RETURN 语句中?
【发布时间】:2014-02-28 16:31:12
【问题描述】:

我正在查看一些 Java 算法示例,并且在递归方法中遇到了这个 sn-p 代码:

boolean subTree(TreeNode t1, TreeNode t2) {
    if (t1 == null) {
        return false;
    }
    if (t1.value == t2.value) {
        if (treeMatch(t1, t2))
            return true;;
    }
    return (subTree(t1.left, t2) || subTree(t1.right, t2));
}

不知道(也从未见过)||之前在 return 语句中使用过,更不用说递归了,真的让我很困惑。我将代码复制到 Eclipse 中以查看它是否有效。然后我替换了||与 && 和 Eclipse 似乎并没有被它打扰。从逻辑上讲,我知道这个递归代码应该沿着 TreeNode t1 的左右子树继续下去,但我正在寻找这个 Java 语法如何工作的更多理论解释。

谁能解释一下背后的含义||和 && 在 Java 的 return 语句中?它在递归方面是什么意思?只有和递归结合使用才有意义吗?

【问题讨论】:

  • 您通常如何使用return 语句?你给它的表达是什么?你可以做return a + b,那为什么不return c || d呢? ||&& 只是运算符。
  • 它是递归的或表达式不相关,也不是递归的表达式。
  • 重点是返回一个布尔值。表达式 **(function(a) && function(b) ) ** 确实是一个布尔值,只要 function(int) 返回一个布尔值。
  • 就像其他人基本上所说的那样,return语句只不过是一个表达式。唯一的“特殊”是它使用递归来评估表达式。另外,考虑用boolean r = (subTree(t1.left, t2) || subTree(t1.right, t2)); 替换该行,然后用return r;

标签: java algorithm recursion syntax return


【解决方案1】:

按照方法签名中的定义,您必须返回一个boolean。因此,在return 关键字之后,您必须提供boolean 或表达式,该表达式会被评估为boolean

在您的情况下,您有表达式(subTree(t1.left, t2) || subTree(t1.right, t2));,其中两个操作数将被评估为boolean,并且只有在第一个评估为false 时,您才会对它们应用逻辑OR。如果第一个操作数的计算结果为 true,则不会计算第二个操作数,并且将返回 true

【讨论】:

    【解决方案2】:

    无论是否存在递归语句,它们的工作方式都是相同的。在你的表达中:

    (subTree(t1.left, t2) || subTree(t1.right, t2))
    

    如果对subTree(t1.left, t2) 的第一次调用计算结果为true,则不会调用或尝试计算第二个表达式。这只是 ||&& 运算符的标准短路行为,也是运算符如何处理给它们的任何参数。

    【讨论】:

    • +1 短路行为信息非常相关,因为我们正在讨论递归调用。
    【解决方案3】:
    return (subTree(t1.left, t2) || subTree(t1.right, t2));
    

    评估第一个子句subTree(t1.left, t2) 然后是第二个。

    因此,一直到叶节点的节点将进行评估,然后开始在树上工作右节点(首先是左节点)。

    【讨论】:

      【解决方案4】:

      这是返回布尔值的逻辑或运算符

       return (subTree(t1.left, t2) || subTree(t1.right, t2))// return boolean value
      

      并且 && 还给你写了布尔值,比如

      return (subTree(t1.left, t2) && subTree(t1.right, t2))// return boolean value
      

      这两个运算符的工作原理与数学逻辑相同

      【讨论】:

        【解决方案5】:

        Java 的return 会返回由方法体定义的单个值。如果您认为它是一个通用函数(它不是,但它有助于理解),它就像您的示例中的return(boolean result)。现在,与任何其他方法一样,您可以进行内联计算,产生一个中间值,然后将其转发(匿名)到实际函数,如Math.round(a + 0.5)

        结合起来

        final boolean result = subTree(t1.left, t2) || subTree(t1.right, t2);
        return result;
        

        变成

        return (subTree(t1.left, t2) || subTree(t1.right, t2));
        

        【讨论】:

          【解决方案6】:

          它们只是布尔值和/或短路。

          短路意味着它评估第一个操作数,然后仅在需要确定结果时才评估第二个操作数。你知道的,真的|| x = 真; false && x = false 无论 x 的值是多少,因此在这些情况下甚至不会对其进行评估。

          如果评估有副作用并且您希望它们总是发生,那么您应该使用 & 或 |不使用短路,因此两个操作数都被计算。

          【讨论】:

            【解决方案7】:

            我会根据[Java Language Specification]来解释:

            return 语句定义为:

            ReturnStatement:
                  return Expressionopt ;

            带有表达式的 return 语句尝试将控制权转移给调用者 包含它的方法; Expression 的值变为值 方法调用

            ...执行这样的 return 语句首先评估表达式

            什么是表达式:

            表达式是由变量运算符和方法调用组成的结构, 它们是根据语言的语法构造的,计算结果为单个值

            return (subTree(t1.left, t2) || subTree(t1.right, t2));
            

            让我们解构它:

            return Expression; //Statement
            
            Expression : (subTree(t1.left, t2) || subTree(t1.right, t2))
            

            如前所述 - 表达式由 方法调用 、运算符等组成 - subTree

            (方法调用子树的结果)逻辑运算符(方法调用子树的结果)

            结果将是表达式的评估值。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-09-12
              • 2017-11-04
              • 2021-03-22
              • 2015-05-14
              • 2015-07-11
              • 2015-12-25
              • 2018-05-15
              • 2014-05-21
              相关资源
              最近更新 更多