我们如何计算大数字的行进距离‽

问题描述 投票:1回答:1

我正在解决此kata:"How far I will go?"

描述中说:

[您最近发现马以独特的方式行走-他们要么在奔跑(以最快的速度),要么在静止(静止)。

这是一匹特定的马可能如何行进的示例:

[Blaze马可以以14米/秒的速度运行60秒,但必须然后休息45秒钟。

500秒后,大火将行驶4200米。

您的工作是编写一个函数,该函数返回一匹马将要骑多久在给定的时间后旅行。

输入:
totalTime - How long the horse will be traveling (in seconds)

runTime - How long the horse can run for before having to rest (in seconds)

restTime - How long the horse have to rest for after running (in seconds)

speed - The max speed of the horse (in metres/second)

我已经手工完成了演算:

给出:速度= 14,运行时间= 60,休息时间= 45,总时间= 500

->要计算马跑多少时间,我们计算以下内容:

totalTime /(runTime + restTime)= 500 /(60 + 45)= 500/105 = 4.76 ...roundUp(totalTime)= 5

totalRunTime = 5 * runTime = 5 * 60 = 300

->计算马走了多少距离:

x =速度* totalRunTime = 14 * 300 = 4200

我将其翻译为以下代码:

public class Kata {

    public static int travel(int totalTime, int runTime, int restTime, int speed) {
      int totalRunTime = 0;

      if(totalTime < runTime){
        totalRunTime = totalTime;
      }else{
        totalRunTime = (int)Math.ceil( (double)totalTime/(runTime + restTime) ) * runTime;
      }

      return speed * totalRunTime;
    }
}

[当我们运行基本测试时,它会提供预期的输出:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;


public class KataTest {

    @Test
    public void exampleTests() {
        assertEquals(4200, Kata.travel(500, 60, 45, 14));
        assertEquals(1120, Kata.travel(1000, 10, 127, 14));
        assertEquals(1000, Kata.travel(100, 10, 0, 10));
        assertEquals(1000, Kata.travel(100, 10, 0, 10));
        assertEquals(450, Kata.travel(25, 50, 120, 18));
    }
}

但是,当我们用大量高级示例进行测试时,它显示的结果不准确。

例如:

给出:速度= 6,运行时间= 34,休息时间= 180,总计时间= 99094;预期的输出是94524,但是我发布的代码给了我们94656

我已经手工编写了跟踪以了解我的代码的作用:

->要计算这匹马奔跑的总时间:

totalTime /(runTime + restTime)= 99094 /(34 + 180)= 99094/214 = 463.05 ...roundUp(totalTime)= 464

totalRunTime = 464 * runTime = 464 * 34 = 15776

->计算马走了多远:

x =速度* totalRunTime = 6 * 15776 = 94656

因此失败的测试是:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.junit.runners.JUnit4;


public class KataTest {

    @Test
    public void biggerTests() {
        assertEquals(84954920, Kata.travel(35869784, 90, 100, 5));
    }
}

我有一种直觉,必须在从double到int的转换或使用Math.ceil进行四舍五入的过程中改进代码,但是我不知道为什么或如何解决它。这是我认为可以改进的行:

totalRunTime = (int)Math.ceil( (double)totalTime/(runTime + restTime) ) * runTime;

我也读过:

java math int double calculus
1个回答
0
投票

问题不在于四舍五入。让我们看一下示例travel(35869784, 90, 100, 5)

根据您的公式35869784/(100+90) = 188788.336,向上舍入得出188789,再乘以runTime,然后乘以speed得到84,955,050米,而正确的答案是84,954,920。这不是一个四舍五入的问题。公式是错误的。

为什么?考虑最后一次运行。我们进行了90,100次运行的188,788次完整迭代,在此过程中,我们在35,869,720秒内行驶了84,954,600米。在这些“满员”奔跑之后,这匹马现在只剩64秒可以跑了,这比runTime还短!

[马在64秒内跑了多远? 320米因此总数为84,954,600 + 320 = 84,954,920米。

© www.soinside.com 2019 - 2024. All rights reserved.