简体   繁体   English

高效的算法,可找到可被数字整除的数的计数,而该数没有范围内的余数

[英]Efficient algorithm to find the count of numbers that are divisible by a number without a remainder in a range

Let's say I have two numbers: 6 and 11 and I am trying to find how many numbers between this range are divisible by 2 (3, in this case). 假设我有两个数字:6和11,并且我试图找出此范围内有多少个数字可被2除(在这种情况下为3)。

I have this simple code right now: 我现在有这个简单的代码:

def get_count(a, b, m):
    count = 0

    for i in range(a, b + 1):
        if i % m == 0:
            count += 1

    return count

Its order of growth is linear, O(N), I believe. 我相信它的增长顺序是线性的O(N)。

I was wondering if there is a faster algorithm with a constant O(1) performance, or a mathematical formula. 我想知道是否有一个更快的算法,具有恒定的O(1)性能或数学公式。

I don't expect a direct answer. 我不希望直接回答。 The name of such an algorithm would be awesome. 这样的算法的名字真是棒极了。

Thank you. 谢谢。

((b - b%m) - a)//m+1 seems to work for me. ((b - b%m) - a)//m+1似乎对我有用。 I doubt it has a name. 我怀疑它的名字。 Another formula that seems to work is (b//m) - ((a-1)//m) . 另一个似乎有效的公式是(b//m) - ((a-1)//m)

Sample python3 program: 示例python3程序:

def get_count(a, b, m):
    return (((b - (b % m)) - a) // m) + 1

for i in range(5, 8):
    for j in range(10, 13):
        print(get_count(i, j, 2), end=" ")
    print()

You are counting even numbers. 您正在计算偶数。 Let's write o for odd, E for even. 让我们写o表示奇数, E表示偶数。

If the sequence has an even count of numbers, it is either oEoE...oE or EoEo...Eo , ie one half of numbers is always even. 如果序列的偶数计数为oEoE...oEEoEo...Eo ,即数字的一半始终为偶数。 If there is odd count of numbers, you can check the first number (or last one) separately and the rest is the known case discussed first. 如果存在奇数个数字,则可以分别检查第一个数字(或最后一个数字),其余是首先讨论的已知情况。

def count_even(start, end):
    # assert start <= end
    len = end - start
    len2, r = divmod(len, 2)
    if r and start % 2 == 0:
        len2 += 1
    return len2

To find the count of all numbers between 0 and n that are divisible by two. 查找0到n之间可被2整除的所有数字的计数。 you can use the bitwise operation called right shift; 您可以使用称为右移的按位运算;

c = a >> 1;

10 >> 1 is equivalent to floor(10/2) 10 >> 1等于floor(10/2)

You can subtract the two resultant numbers and get numbers between any range. 您可以将两个结果数字相减得到任意范围之间的数字。

This will work in O(1). 这将在O(1)中起作用。 Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM