Count the Number of Zero's between Range of integers

时间:2015-09-14 15:55:42

标签: combinatorics number-theory

. Is there any Direct formula or System to find out the Numbers of Zero's between a Distinct Range ... Let two Integer M & N are given . if I have to find out the total number of zero's between this Range then what should I have to do ?

Let M = 1234567890 & N = 2345678901 And answer is : 987654304

Thanks in advance .

2 个答案:

答案 0 :(得分:3)

重新审核问题

这是Ruby中的一个简单解决方案,它检查区间[m,n]中的每个整数,确定标准基数10位置系统中其数字的字符串,并计算出现的0位数:

def brute_force(m, n)
  if m > n
    return 0
  end
  z = 0
  m.upto(n) do |k|
    z += k.to_s.count('0')
  end
  z
end

如果您在交互式Ruby shell中运行它,您将获得

irb> brute_force(1,100)
=> 11

哪个好。但是,使用问题中示例的区间界限

m = 1234567890
n = 2345678901

你会发现这需要相当长的时间。在我的机器上,它确实需要几秒钟,到目前为止我不得不取消它。

因此,真正的问题不仅在于提出正确的零计数,而且要比上述蛮力解决方案更快。

复杂性:运行时间

蛮力解决方案需要执行n-m + 1次搜索基数10字符串中的数字k,其长度为floor(log_10(k))+ 1,因此它不会超过

  

O(n(log(n)+1))

字符串数字访问。慢的例子有一个大约n = 10 ^ 9的n。

降低复杂性

Yiming Rong的回答是第一次尝试降低问题的复杂性。

如果计算关于区间[m,n]的零数的函数是F(m,n),那么它具有属性

  

F(m,n)= F(1,n)-F(1,m-1)

这样就可以用属性

查找最可能更简单的函数G.
  

G(n)= F(1,n)。

分而治之

为函数G提供一个封闭的公式并不容易。例如。 区间[1,1000]包含192个零,但区间[1001,2000]包含300个零,因为第一个区间中k = 99的情况对应于第二个区间中的k = 1099,这会产生另一个零位数数数。 k = 7将显示为1007,产生两个零。

可以尝试的是根据更简单的问题实例的解决方案来表达某个问题实例的解决方案。这种策略在计算机科学中被称为分而治之。如果在某种复杂程度上可以解决问题实例并且如果可以从更简单的解决方案中推断出更复杂问题的解决方案,则它可以工作。这自然会导致递归的表达。

E.g。我们可以为受限制的G版本制定解决方案,这只适用于某些参数。我们将其称为g,它定义为9,99,999等,并且对于这些参数将等于G. 它可以使用此递归函数计算:

# zeros for 1..n, where n = (10^k)-1: 0, 9, 99, 999, ..
def g(n)
  if n <= 9
    return 0
  end
  n2 = (n - 9) / 10
  return 10 * g(n2) + n2
end

请注意,此函数比蛮力方法快得多:要计算区间[1,10 ^ 9-1]中的零,这与问题中的m相当,它只需要9个调用,复杂性

  

O(日志(n))的

再次注意,此g不是针对任意n定义的,仅针对n =(10 ^ k)-1。

g的推导

首先找到函数h(n)的递归定义, 如果十进制表示具有前导零,则从1到n =(10 ^ k)-1的数字中对零进行计数。

示例:h(999)计算数字表示的零位数:

  • 001..009
  • 010..099
  • 100..999

结果将是h(999)= 297.

使用k = floor(log10(n + 1)),k2 = k - 1,n2 =(10 ^ k2) - 1 =(n-9)/ 10函数h结果为

  

h(n)= 9 [k2 + h(n2)] + h(n2)+ n2 = 9 k2 + 10 h(n2)+ n2

初始条件h(0)= 0.它允许将g表示为

  

g(n)= 9 [k2 + h(n2)] + g(n2)

与初始条件g(0)= 0。

从这两个定义中我们也可以定义h和g之间的差异d,再次作为递归函数:

  

d(n)= h(n) - g(n)= h(n2) - g(n2)+ n2 = d(n2)+ n2

初始条件d(0)= 0.尝试一些例子可以得到一个几何系列,例如: d(9999)= d(999)+ 999 = d(99)+ 99 + 999 = d(9)+ 9 + 99 + 999 = 0 + 9 + 99 + 999 =(10 ^ 0)-1 +(10 ^ 1)-1 +(10 ^ 2)-1 +(10 ^ 3)-1 =(10 ^ 4 - 1)/(10-1) - 4.这给出了封闭形式

  

d(n)= n / 9 - k

这允许我们用g表示g:

  

g(n)= 9 [k2 + h(n2)] + g(n2)= 9 [k2 + g(n2)+ d(n2)] + g(n2)= 9 k2 + 9 d(n2 )+ 10 g(n2)= 9 k2 + n2 - 9 k2 + 10 g(n2)= 10 g(n2)+ n2

G的推导

使用上面的定义并命名表示q_k,q_k2,..,q2,q1的k个数字,我们首先将h扩展为H:

  

H(q_k q_k2..q_1)= q_k [k2 + h(n2)] + r(k2-kr)+ H(q_kr..q_1)+ n2

初始条件H(q_1)= 0,q_1 <= 9。

请注意附加定义r = q_kr..q_1。要理解为什么需要它,请查看示例H(901),其中对H的下一级调用是H(1),这意味着数字字符串长度从k = 3缩小到kr = 1,需要额外的填充r(k2-kr)零位数。

使用它,我们也可以将g扩展为G:

  

G(q_k q_k2..q_1)=(q_k-1)[k2 + h(n2)] + k2 + r(k2-kr)+ H(q_kr..q_1)+ g(n2)

初始条件G(q_1)= 0,q_1 <= 9。

注意:很可能可以像上面的g一样简化上面的表达式。例如。试图用G表示G而不是使用h和H.我将来可能会这样做。以上已足以实现快速零计算。

测试结果

recursive(1234567890, 2345678901) =
  987654304
expected:
  987654304
success

有关详细信息,请参阅sourcelog

更新:我根据比赛中更详细的问题描述更改了源和日志(允许0作为输入,处理无效输入,第2个更大的示例)。

答案 1 :(得分:1)

You can use a standard approach to find m = [1, M-1] and n = [1, N], then [M, N] = n - m.

Standard approaches are easily available: Counting zeroes.