【问题标题】:Finding larger number within a range在一个范围内找到更大的数字
【发布时间】:2015-10-29 22:32:33
【问题描述】:

我一直在处理这些 CodingBat 问题,但遇到了另一个问题。

任务是这样的:

给定 2 个正 int 值,返回 10..20 范围内的较大值,如果两者都不在该范围内,则返回 0。

一些例子:

  • max1020(11, 19) → 19
  • max1020(19, 11) → 19
  • max1020(11, 9) → 11

我的解决办法是:

public int max1020(int a, int b) {
    if (((a >= 10 && a <= 20) || (b >= 10 && b <= 20)) && a >= b) {
        return a;
    }

    if (((a >= 10 && a <= 20) || (b >= 10 && b <= 20)) && b >= a) {
        return b;
    } else {
        return 0;
    }
}

代码在超过一半的时间内返回了正确的输出,但在某些情况下它没有按预期工作。场景是输入为 (10,21),(21,10),(23,10) 时。

这很奇怪,因为我明确排除了 #>20,但对于上述三种情况,它分别返回 21、21 和 23。

我在哪里做错了?

【问题讨论】:

  • 试着把你的比较器写成(10=&lt;a &amp;&amp; a&lt;=20),这样更容易阅读和发现错误。
  • 检查范围后,您会查找两个数字中的最大值,例如 21,19 19 在范围内但 21 不在范围内,您的 if 条件通过但您返回两个数字的最大值,即21.请注意21不在范围内。
  • 不知道你写到这里有没有漏掉,但是第二个if之前应该有一个else。还有其他问题,但您应该先解决这个问题。

标签: java


【解决方案1】:

让我们来看看它们。

(10,21):

if(((10 >= 10 && 10 <= 20) || (21>=10 && 21<=20)) && 10>=21)
  (((true and true) || (true and false)) && false)
  ((true) && false)
  false

好吧,不是那个。

if(((10 >= 10 && 10 <= 20) || (21>=10 && 21<=20)) && 21>=10)
  (((true and true) || (true and false)) && false)
  ((true) and true)
  true

-> return 21

好的,为什么会这样?因为您的逻辑说“如果任一值在范围内,则返回较大的值,即使较大的值不在范围内”。

相反,如果一个值超出范围,甚至不要考虑它。这是一个可能的开始:

if(a < 10 && a > 20) {
    // do something with only b. This is where you would return zero, too.
} else if(b < 10 && b > 20) {
    // do something with only a
} else {
    // do something with both
}

【讨论】:

  • 这是一种很好的分析方法,我想我现在有点明白了。会尝试再解决一次。
  • 我最终使用了完全不同的方法,但感谢您的彻底回复,帮助我以不同的方式看待我的逻辑链。
【解决方案2】:

你的逻辑基本上是这样说的:

  • 如果ab在范围内,并且a大于或等于b,则返回a
  • 如果ab在范围内,并且b大于或等于a,则返回b
  • 返回 0。

因此,如果a 在范围内但b 更大(并且超出范围),则仍会返回b

将您的逻辑更改为:

  • 如果a在范围内且a大于或等于b,则返回a
  • 如果b在范围内且b大于或等于a,则返回b
  • 返回 0。

【讨论】:

    【解决方案3】:
    Boolean aInRange = (a >= 10 && a <= 20)
    
    Boolean bInRange = (b >= 10 && b <= 20)
    
    int max = 0;
    
    if (aInRange && bInRange) {
    
        if(a >= b)
            max = a;
        else {
            max = b;
        }
    } else if (!bInRange && aInRange) {
        max = a;
    }
    else if (bInRange && !aInRange) {
        max = b;
    }
    return max;
    

    【讨论】:

      【解决方案4】:

      如果任一值在范围内,您的代码将返回较大的值。

      鉴于这些问题的性质,您应该尝试使用test driven approach 来开发您的方法,这也可以确保您的代码按照您的预期运行。当您在 CodingBat 上提交代码时,类似于下面的测试可能正在测试您的代码。

      public class SandBox {
          public int max1020(int a, int b) {
              if (10 <= a && a <= 20) { // if a is in range
                  if (a >= b || b > 20) { // if a is greater than B or B is out of range
                      return a;
                  }
              }
      
              //
              if (10 <= b && b <= 20) { // if b is in range
                  return b;
              }
      
              return 0;
          }
      }
      

      测试

      import org.junit.Before;
      import org.junit.Test;
      
      import static org.hamcrest.MatcherAssert.assertThat;
      import static org.hamcrest.Matchers.is;
      
      public class SandBoxTest {
          SandBox sand;
      
          @Before
          public void given(){
              sand = new SandBox();
          }
      
          @Test
          public void testOne(){
              int i = sand.max1020(1, 2);
              assertThat(i, is(0));
          }
      
          @Test
          public void testTwo(){
              int i = sand.max1020(2, 1);
              assertThat(i, is(0));
          }
      
          @Test
          public void testThree(){
              int i = sand.max1020(5, 10);
              assertThat(i, is(10));
          }
      
          @Test
          public void testFour(){
              int i = sand.max1020(10, 5);
              assertThat(i, is(10));
          }
      
          @Test
          public void testFive(){
              int i = sand.max1020(11, 15);
              assertThat(i, is(15));
          }
      
          @Test
          public void testSix(){
              int i = sand.max1020(15, 11);
              assertThat(i, is(15));
          }
      
          @Test
          public void testSeven(){
              int i = sand.max1020(20, 23);
              assertThat(i, is(20));
          }
      
          @Test
          public void testEight(){
              int i = sand.max1020(23, 20);
              assertThat(i, is(20));
          }
      
          @Test
          public void testNine(){
              int i = sand.max1020(33, 25);
              assertThat(i, is(0));
          }
      
          @Test
          public void testTen(){
              int i = sand.max1020(25, 33);
              assertThat(i, is(0));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-28
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 1970-01-01
        • 2017-08-06
        相关资源
        最近更新 更多