一尘不染

从1到N的整数计算0的出现次数

algorithm

您如何有效地计算从1到N的整数的十进制表示形式中0的出现次数?

e.g. The number of 0's from 1 to 105 is 16. How?

10,20,30,40,50,60,70,80,90,100,101,102,103,104,105

计算0的数量,您会发现它为16。

显然,蛮力方法将不被赞赏。您必须提出一种不依赖于“有多少个数字介于1到N之间”的方法。我们可以通过观察某种模式来做到吗?

我们不能扩展此处编译逻辑以解决此问题吗?


阅读 439

收藏
2020-07-28

共1个答案

一尘不染

更新的答案

我最初的答案很容易理解,但是很难编写代码。这是一些更容易编写的代码。这是一种直接的 非递归 解决方案,它通过计算零在每个位置出现的方式的数量来工作。

例如:

x <=1234。以下形式的数字是多少?

x = ?? 0?

“一百个或更多”(1,2,…,12)有12种可能性。然后必须为零。那么最后一位数字有10种可能性。这给出12 * 10 = 120了在第三位包含0的数字。

因此,范围(1到1234)的解决方案是:

  • 0:1 * 100 = 100
  • ?? 0 ?: 12 * 10 = 120
  • 0:123
  • 总计= 343

但是,如果n包含零位是例外。考虑以下情况:

x <=12034。以下形式的数字是多少?

x = ?? 0 ??

我们有12种选择“数千个或更多”的方法。对于1、2,… 11,我们可以选择最后两个数字(给出11 * 100的可能性)。但是,如果我们开始与12,我们只能选择之间的数字0034最后两位数字。因此,我们11 * 100 + 35完全有可能。


这是此算法的实现(用Python编写,但以易于移植到C的方式):

def countZeros(n):
    result = 0
    i = 1

    while True:
        b, c = divmod(n, i)
        a, b = divmod(b, 10)

        if a == 0:
            return result

        if b == 0:
            result += (a - 1) * i + c + 1
        else:
            result += a * i

        i *= 10
2020-07-28