如何从0-59整数数组按步长返回连续数字块 实现二进制时钟位判断
核心问题拆解
你要的分段取数逻辑,本质和二进制位的亮灯规则完全对齐,根本不需要手动凑遍历逻辑绕弯:
对于权重为w的二进制亮灯位(w为1、2、4、8这类2的整数次幂),所有满足“需要点亮”的数值是完全有固定规律的:
- 每
2*w的长度为一个完整大周期 - 每个周期里,从第
w个位置开始,连续取w个数字(这就是你要的连续块) - 跳过紧跟在这个块后面的
w个数字,进入下一个大周期重复上述逻辑
对应你给的示例核对:
- 权重w=2:大周期长度为
2*2=4,每个周期从位置2开始取2个连续数(2、3),跳过后面2个(4、5),下一个周期从6开始取(6、7),输出完全和你要求的一致 - 权重w=4:大周期长度为
2*4=8,每个周期从位置4开始取4个连续数(4、5、6、7),跳过后面4个(8、9、10、11),下一个周期从12开始取(12、13、14、15),也完全匹配示例
你之前代码输出不对的核心原因:把步长设成了w,且每次循环只取数组中下标等于i的单个值,没有取连续的数字块,所以才会输出2、4、6这类零散的隔位数值。
可直接复用的实现
通用取数函数
不管权重是多少,只要传入对应权重值和最大值(时间范围上限是59),就能返回所有符合要求的数字块:
/** * 取对应二进制权重下所有需要点亮的数字块 * @param {number} weight 二进制位权重,如1/2/4/8/16 * @param {number} totalMax 时间范围最大值,默认59 * @returns {Array<Array<number>>} 按连续块分组的匹配数值 */ function getMatchedGroups(weight, totalMax = 59) { const blockSize = weight; // 单个连续块的长度=权重值 const cycleStep = 2 * weight; // 跨块的跳转步长=两倍权重 const groups = []; for (let start = weight; start <= totalMax; start += cycleStep) { const currentGroup = []; // 从块起始位置连续取数,处理最后一块超出最大值的边界情况 for (let num = start; num < start + blockSize && num <= totalMax; num++) { currentGroup.push(num); } groups.push(currentGroup); } return groups; }
调用效果验证:
- 传入参数
getMatchedGroups(2),返回分组展开为[2,3], [6,7], [10,11], ..., [58,59] - 传入参数
getMatchedGroups(4),返回分组展开为[4,5,6,7], [12,13,14,15], [20,21,22,23], ...
修正后可直接跑的HTML测试代码
把你原来的测试脚本替换成下面的内容,直接就能出对应效果:
<p id="test"></p> <script> const targetWeight = 2; // 改成4即可测试权重为4的输出效果 const totalRangeMax = 59; const blockSize = targetWeight; const jumpStep = 2 * targetWeight; let outputText = ""; for (let blockStart = targetWeight; blockStart <= totalRangeMax; blockStart += jumpStep) { const groupItems = []; for (let num = blockStart; num < blockStart + blockSize && num <= totalRangeMax; num++) { groupItems.push(num); } outputText += groupItems.join(", ") + "<br>"; } document.getElementById("test").innerHTML = outputText; </script>
针对二进制时钟场景的简化优化
其实你根本不需要提前把所有匹配值存在数组里做比对,判断某个时间值该不该点亮对应位,直接用位运算就行:
对于当前时间值
currentValue,对应位权重是w,只要判断(currentValue & w) !== 0,结果为真就点亮该灯,连取段、遍历数组的步骤都可以省掉,代码量会少很多。
举个实际使用的例子:
- 秒数为3,权重w=2,计算得
3 & 2 = 2非0,点亮对应位 - 秒数为14,权重w=4,计算得
14 &4 =4非0,点亮对应位 - 秒数为7,同时满足w=2、w=4的位判定条件,两个对应灯同时点亮,完全符合二进制时钟的亮灯逻辑。
内容的提问来源于stack exchange,提问作者ScoobyDooku
相关产品推荐
相关产品推荐

