【问题标题】:Check if int is between two numbers检查 int 是否在两个数字之间
【发布时间】:2010-12-31 20:49:15
【问题描述】:

如果你试图找出一个 int 是否介于两个数字之间,为什么不能这样做:

if(10 < x < 20)

你必须这样做

if(10<x && x<20)

这似乎有点开销。

【问题讨论】:

  • 开销如何?我认为你低估了 java 运行时......
  • 好吧,也许开销是一个大词。但是为什么我们不能这样做。我每次在数学课上都写它。
  • 因为这是 Java 使用的语法。没有“为什么”,就是这样。
  • @Timo Willemsen - 回复上面的评论;也许您所看到的内容因您的数学使用而有些恶化,但在日常使用中(在通用语言中)这不是一个大问题,因此不值得使用不同的语法。
  • 不管 Java 是否会改变,挑战这种设计决策并不是异端邪说。您可能会发现“自然编程”研究发人深省。他们研究诸如要求人们去水果箱并“带回不是苹果或梨的东西”之类的事情。如果你不以非常夸张的方式唱“或”,很少有人会带着梨回来......因为我们听到的是 (not (apple or pear)) 而不是 (not apple) 或 (pear )。我们可以调整语言以更好地满足人类的期望。见:cs.cmu.edu/~NatProg/index.html

标签: java integer conditional-operator


【解决方案1】:

因为根本没有定义语法?此外,x &lt; y 评估为布尔值,那么bool &lt; int 是什么意思?这并不是真正的开销。此外,如果你真的想要的话,你可以编写一个实用方法 - isBetween(10,x,20) - 我不会我自己,但是嘿...

【讨论】:

  • 奇怪的是,我希望 isBetween() 方法的第一个参数是要测试的值,第二个和第三个参数是上限和下限。不要让我给你一个理由,这样感觉更理智。
  • 老实说,我不会因为担心订单而兴奋。嘿,我主要是 C# 人,所以我可以添加一个扩展方法:if(x.IsBetween(10,20)) {...} ;-p
  • @Marc:为什么不更进一步:if (x.IsBetween(10).And(20)) :-)
  • @Cellfish:流体 API 一切都很好,很闪亮,但你太过分了:x.IsBetween(10) 是什么意思?
  • 那是什么答案? OP不知道语法没有定义吗?你认为三元运算符不能存在吗?
【解决方案2】:

因为&lt; 运算符(和大多数其他运算符)是二元运算符(它们有两个参数),而(true true) 不是有效的布尔表达式。

Java 语言设计者本可以将语言设计为允许使用您喜欢的类型的语法,但是(我猜)他们认为不值得使用更复杂的解析规则。

【讨论】:

    【解决方案3】:

    这只是语法。 '

    语法始终是复杂性、表达性和可读性之间的权衡。不同的语言设计者做出不同的选择。例如,SQL 有“x BETWEEN y AND z”,其中 x、y 和 z 可以单独或全部是列、常量或绑定变量。我很高兴在 SQL 中使用它,我同样很高兴不用担心为什么它不在 Java 中。

    【讨论】:

    • 然而,只有这样的结构可以在 python 中使用。
    • 其实我更喜欢 Marc 的回答。
    【解决方案4】:

    COBOL 允许这样做(我相信其他一些语言也可以)。 Java从不允许它的C继承了大部分语法。

    【讨论】:

    • 很明显,自从我上次在 COBOL 中开发一些东西以来,很多水已经从桥下流过,因为我不记得了。只是因为我疯了,想刷新我的记忆,你能不能用一行大写评论:-)
    • 我很确定我记得在 COBOL 中这样做(嗅探)
    • 显然使用不同的语法是:)
    • @TofuBeer:好的,我要了:-D
    • Common Lisp 允许此类比较运算符的任何正数。在&lt;', the arguments must be monotonically increasing for it to evaluate to t'的情况下。见lispworks.com/documentation/HyperSpec/Body/f_eq_sle.htm#LT
    【解决方案5】:

    您是人类,因此您理解术语“10

    例如,如果 x = 15,它将计算:

    (10 正确

    "真 ???

    在 C 编程中,情况会更糟,因为没有 True\False 值。 如果 x = 5,则计算为:

    10 0 (False 的值)

    0 非 0 数(真)

    因此 "10

    【讨论】:

    • 我知道它是如何工作的。但是,编程语言难道不应该让人类的事情变得简单吗?否则我们仍然会编写汇编或二进制代码。
    • 这是很重要的一点:使 "10
    • Timo - 您可能会发现这篇感兴趣的文章:blogs.msdn.com/ericgu/archive/2004/01/12/57985.aspx。请记住,必须有人来实现您的请求,并对其进行调试、测试和维护。
    • 有人认为多重继承和宏也是一个好主意。也许吧,但代价是什么?
    • 这不是一般计算机固有的东西,只是大多数流行的编程语言。正如其他人所指出的,一些编程语言允许更数学化的10 &lt; x &lt; 20 语法。
    【解决方案6】:

    如果允许使用10 &lt; x &lt; 20,与语言复杂性的增加相比,输入10 &lt; x &amp;&amp; x &lt; 20 的不便是最小的,因此Java 语言的设计者决定不支持它。

    【讨论】:

      【解决方案7】:

      一个问题是三元关系构造会引入严重的解析器问题:

      <expr> ::= <expr> <rel-op> <expr> |
                 ... |
                 <expr> <rel-op> <expr> <rel-op> <expr>
      

      当您尝试使用典型的 PGS 来表达这些产生式的语法时,您会发现在第一个 &lt;rel-op&gt; 处存在移位归约冲突。解析需要先行查看任意数量的符号,以查看是否有第二个&lt;rel-op&gt;,然后才能确定使用的是二进制形式还是三进制形式。在这种情况下,您不能简单地忽略冲突,因为这会导致解析不正确。

      我并不是说这个语法是致命的模棱两可。但我认为你需要一个回溯解析器来正确处理它。对于以快速编译为主要卖点的编程语言来说,这是一个严重的问题。

      【讨论】:

      • 并非如此。请参阅 docs.python.org/reference/expressions.html#notindocs.python.org/reference/grammar.html 了解 Python 如何处理它。
      • @Adam - 这很奇怪。语法允许“1
      • 使用你的第一个产品允许(&lt;expr&gt; &lt;rel-op&gt; &lt;expr&gt;) &lt;rel-op&gt; &lt;expr&gt;,这将是你的第三行的解析(因为Java关系操作是左关联的)。我没有看到您的示例如何证明您的观点。
      • @EricTowers - 当然。但这无关紧要。关键是解析器必须理解用户没有包含括号的情况。当你有一个包含两个运算符和 3 个操作数的单一构造时,正常的关联性实际上并不适用。
      【解决方案8】:

      你可以自己做

      public static boolean isBetween(int a, int b, int c) {
          return b > a ? c > a && c < b : c > b && c < a;
      }
      

      编辑:抱歉检查 c 是否在 a 和 b 之间

      【讨论】:

      • 这不能正常工作,因为如果你检查 10 到 20 之间并且你想检查 20 它返回 false。
      • @EvilP 这是主要的;从字面上看,介于两个值之间。如此独特。
      • Java 默认库不包含这样的东西吗?
      • 如何包含边界值?假设 a = 100 和 b= 200 和 c= 100。如何使这个条件也成立?在目前的情况下它是错误的
      【解决方案9】:

      if (10 &lt; x || x &lt; 20)

      此语句将评估 10 到 20 之间的数字为真。 这大致相当于10 &lt; x &lt; 20

      【讨论】:

      • 10 &lt; x || x &lt; 20 等价于x &lt; 20,因为所有小于 10 的(实数)数字也都小于 20。另一方面,10 &lt; x &lt; 20 等价于 10 &lt; x &amp;&amp; x &lt; 20
      • 这个表达式有错误,所有大于10小于20的实数,所以总是正确的。
      • 应该是“&&”,而不是“||”。
      【解决方案10】:

      简化:

      a = 10; b = 15; c = 20
      
      public static boolean check(int a, int b, int c) {
          return a<=b && b<=c;
      }
      

      这会检查 b 是否在 a 和 c 之间

      【讨论】:

        【解决方案11】:

        可以使用 Guava 库中的 Range 类:

         Range.open(10, 20).contains(n)
        

        Apache Commons Lang 也有类似的类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多