从总秒数数组的中位数中查找确切的小时数、分钟数、秒数
Finding exact number of hours, minutes, seconds from median of array of total number of seconds
作为整体挑战的一部分,我需要我的代码找到表示总秒数的数字数组(具有偶数或奇数个元素)的中位数,并将该数字转换为包含小时、分钟和总秒数中的秒数。该代码运行良好,但未通过测试,尤其是随机测试。在每种情况下,总秒数都比测试显示少一秒或多一秒。
如何使用当前代码解决这个问题,或者我应该做一些完全不同的事情?
我已经尝试使用不同的数学方法来处理代码,但我仍然遇到秒数比正确答案高或低一秒的问题。
到目前为止,这是我的代码:
concatInt = [ 3432, 4331, 7588, 8432 ]
let rawMedian = function (){
if(concatInt.length === 0) return 0;
concatInt.sort(function(a,b){
return a-b;
});
var half = Math.floor(concatInt.length / 2);
if (concatInt.length % 2)
return concatInt[half];
return (concatInt[half - 1] + concatInt[half]) / 2.0;
}
let toStopwatch = function(){
let hours;
let minutes;
let seconds;
if (rawMedian()/3600 > 1){
hours = Math.floor(rawMedian()/3600);
minutes = ((rawMedian() % 3600)/60);
seconds = Math.floor((minutes - Math.floor(minutes)) * 60);
if (seconds === 60){
seconds = seconds -1;
}
} else {
hours = 0;
if (rawMedian() > 60){
minutes = (rawMedian()/60);
seconds = Math.floor((minutes - Math.floor(minutes)) * 60);
if (seconds === 60){
seconds = seconds -1;
}
} else {
minutes = 0;
seconds = rawMedian()
}
}
let timesArr = [];
timesArr.push(`${hours.toString()}`, `${Math.floor(minutes).toString()}`, `${seconds.toString()}`);
return timesArr;
}
此代码的结果是 ["1", "39", "19"]。但是,在 Codewars Kata 测试中,上述代码显示不正确,因为秒数比预期秒数多或少一秒。我很乐意根据要求提供我的完整代码和涉及的具体 Kata,但上面的代码显然是导致问题的原因。
有几个问题,但前两个可以解释为什么你会得到一秒的差异:
当concatInt
数组有偶数个值时,中位数会有半秒。你没有说那半秒应该发生什么,但你似乎把它截断了。很可能要求是 round 它。
你计算秒的方式容易出现浮点不精确错误:
Math.floor((minutes - Math.floor(minutes)) * 60)
例如,如果 minutes
是 8.6,那么这个表达式 - 在应用 Math.floor
之前 - 将导致:35.99999999999998 而不是 36。你应该避免在那里乘以 60。相反,您可以像这样获得秒数:
median % 60
你重复调用rawMedian
,这是浪费时间。只需调用一次并将结果存储在变量中以供进一步使用。
if (seconds === 60)
条件永远不会发生。该代码可以删除。
- 您使用的其他
if
构造也不是必需的。中位数是否大于1与计算无关。
- 小时、分钟和秒应该作为字符串而不是数字返回,这似乎很奇怪。如果确实如此,那么使用模板文字 和 调用
toString()
方法就太过分了。两种策略中的一种就足够了。
因此,假设中位数应 舍入 ,代码如下所示:
const toStopwatch = function() {
// Call rawMedian only once.
// Round it (or if it needs to be truncated, use Math.floor).
const median = Math.round(rawMedian());
// Calculation of seconds should just be a modulo 60.
// No special cases need to be distinguished.
// Do not cast to strings, unless explicitly required
return [
Math.floor(median / 3600), // hours
Math.floor((median % 3600) / 60), // minutes
median % 60 // seconds
];
}
作为整体挑战的一部分,我需要我的代码找到表示总秒数的数字数组(具有偶数或奇数个元素)的中位数,并将该数字转换为包含小时、分钟和总秒数中的秒数。该代码运行良好,但未通过测试,尤其是随机测试。在每种情况下,总秒数都比测试显示少一秒或多一秒。
如何使用当前代码解决这个问题,或者我应该做一些完全不同的事情?
我已经尝试使用不同的数学方法来处理代码,但我仍然遇到秒数比正确答案高或低一秒的问题。
到目前为止,这是我的代码:
concatInt = [ 3432, 4331, 7588, 8432 ]
let rawMedian = function (){
if(concatInt.length === 0) return 0;
concatInt.sort(function(a,b){
return a-b;
});
var half = Math.floor(concatInt.length / 2);
if (concatInt.length % 2)
return concatInt[half];
return (concatInt[half - 1] + concatInt[half]) / 2.0;
}
let toStopwatch = function(){
let hours;
let minutes;
let seconds;
if (rawMedian()/3600 > 1){
hours = Math.floor(rawMedian()/3600);
minutes = ((rawMedian() % 3600)/60);
seconds = Math.floor((minutes - Math.floor(minutes)) * 60);
if (seconds === 60){
seconds = seconds -1;
}
} else {
hours = 0;
if (rawMedian() > 60){
minutes = (rawMedian()/60);
seconds = Math.floor((minutes - Math.floor(minutes)) * 60);
if (seconds === 60){
seconds = seconds -1;
}
} else {
minutes = 0;
seconds = rawMedian()
}
}
let timesArr = [];
timesArr.push(`${hours.toString()}`, `${Math.floor(minutes).toString()}`, `${seconds.toString()}`);
return timesArr;
}
此代码的结果是 ["1", "39", "19"]。但是,在 Codewars Kata 测试中,上述代码显示不正确,因为秒数比预期秒数多或少一秒。我很乐意根据要求提供我的完整代码和涉及的具体 Kata,但上面的代码显然是导致问题的原因。
有几个问题,但前两个可以解释为什么你会得到一秒的差异:
当
concatInt
数组有偶数个值时,中位数会有半秒。你没有说那半秒应该发生什么,但你似乎把它截断了。很可能要求是 round 它。你计算秒的方式容易出现浮点不精确错误:
Math.floor((minutes - Math.floor(minutes)) * 60)
例如,如果
minutes
是 8.6,那么这个表达式 - 在应用Math.floor
之前 - 将导致:35.99999999999998 而不是 36。你应该避免在那里乘以 60。相反,您可以像这样获得秒数:median % 60
你重复调用
rawMedian
,这是浪费时间。只需调用一次并将结果存储在变量中以供进一步使用。if (seconds === 60)
条件永远不会发生。该代码可以删除。- 您使用的其他
if
构造也不是必需的。中位数是否大于1与计算无关。 - 小时、分钟和秒应该作为字符串而不是数字返回,这似乎很奇怪。如果确实如此,那么使用模板文字 和 调用
toString()
方法就太过分了。两种策略中的一种就足够了。
因此,假设中位数应 舍入 ,代码如下所示:
const toStopwatch = function() {
// Call rawMedian only once.
// Round it (or if it needs to be truncated, use Math.floor).
const median = Math.round(rawMedian());
// Calculation of seconds should just be a modulo 60.
// No special cases need to be distinguished.
// Do not cast to strings, unless explicitly required
return [
Math.floor(median / 3600), // hours
Math.floor((median % 3600) / 60), // minutes
median % 60 // seconds
];
}