区间内的位数

Number of digits within an interval

我需要计算每个数字在从 1 到 给定数字.

的数字序列中出现的次数

示例:

输入:12

输出:5 2 1 1 1 1 1 1 1 1

解释:

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2

第一个数字是一个的数量,第二个是两个...最后一个是零

到目前为止,我已经编写了一个将任何整数拆分为多个部分的函数(2512 将是 2000 500 10 2)。也许对以后的执行有用:

                function splitToParts(x) {
                var multiplier = 1;

                while (x > 0) {
                    var result = x % 10;

                    if (result > 0) {
                        parts.unshift(result * multiplier);
                    }

                    x = Math.floor(x / 10);
                    multiplier *= 10;
                }
            }

2000、500 和 10 不是数字,因此对于直接计数而言,它们是不可行的。一个简单的方法是说您总是对最低有效数字("ones")和 "consume" 感兴趣,只要它不是 0。

对于单个数字,它会很简单:

function digits(number){
    var retval=[0,0,0,0,0,0,0,0,0,0];
    while(number>0){
        retval[number%10]++;
        number=Math.floor(number/10);
    }
    return retval;
}
console.log(digits(123).join()); // join just makes it a single line, looks better

然后可以通过接受参数使统计数据可更新。它甚至不必是强制性的,如果缺少它,函数可以简单地创建它:

function digits(number,stats){
    var retval=stats || [0,0,0,0,0,0,0,0,0,0];
    while(number>0){
        retval[number%10]++;
        number=Math.floor(number/10);
    }
    return retval;
}

var stats=digits(123);
console.log(stats.join());
console.log(digits(234,stats).join());

并使其循环:

function digits(number,stats){
    var retval=stats || [0,0,0,0,0,0,0,0,0,0];
    while(number>0){
        retval[number%10]++;
        number=Math.floor(number/10);
    }
    return retval;
}

function intervalDigits(min,max){
    var stats;
    for(var i=min;i<=max;i++)
        stats=digits(i,stats);
    return stats;
}

console.log(intervalDigits(1,12).join());

那将是 "brute force",但在 JavaScript 中有效的解决方案。

然后可以去求数学而不是暴力破解,并开始使用 2000-500-10-2 "decomposition",找到 "contribution" 中的模式到 [= 的数字统计数据60=]、'tens'、'hundreds' 等。这些贡献并非微不足道,因此现有的片段可能有助于检查不同 "transitions".

周围发生的情况。

function digits(number,stats){
    var retval=stats || [0,0,0,0,0,0,0,0,0,0];
    while(number>0){
        retval[number%10]++;
        number=Math.floor(number/10);
    }
    return retval;
}

function intervalDigits(min,max){
    var stats;
    for(var i=min;i<=max;i++)
        stats=digits(i,stats);
    return stats;
}

for(var i=1;i<21;i++)console.log("1-"+i,intervalDigits(1,i).join());
console.log("---");
for(var i=95;i<115;i++)console.log("1-"+i,intervalDigits(1,i).join());
console.log("---");
var x100=intervalDigits(1,100);
var x200=intervalDigits(1,200);
var x300=intervalDigits(1,300);
console.log("1-100",x100.join());
console.log("1-200",x200.join());
console.log("1-300",x300.join());
console.log("---");
console.log("1-100 -> 1-200",x200.map((x,i)=>x-x100[i]).join());
console.log("1-200 -> 1-300",x300.map((x,i)=>x-x200[i]).join());
console.log("1-100 -> 1-300",x300.map((x,i)=>x-x100[i]).join());

考虑到 1018 的范围,您很可能(也)追求这条赛道,但此时此地 'starter pack' 就是我所拥有的是时候了。