如何在python中计算多种情况(C)在给定范围(A到B)中可被N整除的数字

Posted

技术标签:

【中文标题】如何在python中计算多种情况(C)在给定范围(A到B)中可被N整除的数字【英文标题】:how to count the number divisible by N in given range (A to B) for multiple cases (C) in python 【发布时间】:2022-01-15 07:05:37 【问题描述】:

所以基本上,有多种情况需要通过计算在给定范围 A 到 B 中能被 N 整除的数字来解决。

例如,有2种情况。

案例 1 有 A=1, B=10, N=3

案例 2 有 A=8,B=20,N=4

但在一个条件下,输入必须是这样的:

2        #<-- number of cases
1        #<-- A 
10       #<-- B 
3        #<-- N
8        #<-- A
20       #<-- B
4        #<-- N

输出会是这样的:

Case 1: 3 #because between 1 until 10, only 3,6,9 that divisible by 3
Case 2: 4 #because between 8 until 20, only 8,12,16,20 that divisible by 4

我有这个功能供参考:

def CountDiv(A,B,N):
    count = 0
    
    for i in range(A, B+1):
        if i % N == 0:
            count = count + 1
    
    return count

我的解释很糟糕,但我只是不知道如何使它更清楚。我希望有人能理解并启发我这个问题。谢谢

【问题讨论】:

你有什么问题?看来您有一个功能可以满足您的需求... 您是在问是否可以优化您的算法? [A,B]范围内能被N整除的整数个数为:B//N - (A-1)//N @UlisesBussi 所以我要问的是如何从输入中分割 A、B 和 N。像示例输入和输出 【参考方案1】:

CountDiv 函数有效。所以,我假设你在问如何正确分割你的输入列表。如果您的输入序列在列表中,这应该可以工作

seq = [ 2,        #<-- number of cases
        1,        #<-- A 
        10,       #<-- B 
        3,        #<-- N
        8,        #<-- A
        20,       #<-- B
        4,        #<-- N
]


def slices(lst, n):

    number_of_cases = lst.pop(0)
    
    for i in range(0, n * number_of_cases, n):
        yield lst[i:i + n]


def CountDiv(A,B,N):
    
    count = 0
    for i in range(A, B+1):
        if i % N == 0:
            count = count + 1
    
    return count

print([CountDiv(*sub) for sub in [*slices(seq, n=3)]])
# [3, 4]

如果你想要你描述的确切输出,你可以这样做

for idx, sub in enumerate([*slices(seq, n=3)]):
    print(f"Case idx: CountDiv(*sub)")

# Case 0: 3
# Case 1: 4

您还应该将@mozway's 和我的答案结合起来,就像这样。

def slices(lst, n):
   
    number_of_cases = lst.pop(0)
     
    for i in range(0, n * number_of_cases, n):
        yield lst[i:i + n]

def ndiv(A, B, N):
    return (B+N-(A+N-1)//N*N)//N if B>=A else 0

for idx, sub in enumerate([*slices(seq, n=3)]):
    print(f"Case idx: ndiv(*sub)")

按需编辑* 运算符在上面两次用于unpack elements from an iterable。例如,在上面的语句中,ndiv(*sub) 可以替换为 ndiv(sub[0], sub[1], sub[2])。如果我们想让它变得非常冗长,我们可以这样写

result_of_slicing = list(slices(seq, n= 3))
# [[1, 10, 3], [8, 20, 4]]

for index, a_slice in enumerate(result_of_slicing):

    A, B, N = a_slice
    result_of_ndiv = ndiv(A=A, B=B, N=N)
    
    print(f"Case index: result_of_ndiv")
    # Case 0: 3
    # Case 1: 4

【讨论】:

你能解释一下 *slices 和 *sub 是什么意思吗?我还在学习对不起。您的回答很好,但我想在应用此方法之前了解它。 @GilangArindawa 我对*operator 的作用添加了更详细的解释。希望有帮助! 哦,我明白了,这很有帮助。谢谢 没问题。如果回答了您的问题,请考虑将答案标记为正确。【参考方案2】:

您不需要遍历所有值。只能从最小起点((A+N-1)//N*N)生成倍数:

def ndiv(A, B, N):
    return len(list((A+N-1)//N*N, B+1, N)))

更好的是,使用以下方法直接计算值的数量:

def ndiv(A, B, N):
    if B<A:
        return 0
    return (B+N-(A+N-1)//N*N)//N

示例:

>>> ndiv(8,20,4)
4

>>> ndiv(1,10,3)
3

>>> ndiv(1,1,3)
0

【讨论】:

以上是关于如何在python中计算多种情况(C)在给定范围(A到B)中可被N整除的数字的主要内容,如果未能解决你的问题,请参考以下文章

在给定稀疏矩阵数据的情况下,Python 中计算余弦相似度的最快方法是啥?

计算给定范围内 AVL 树中的节点数

Python列表如何识别给定数字在挑战问题范围内[关闭]

如何使用 Moment JS 计算范围之间的给定工作日数?

JAVA随机数之多种方法从给定范围内随机N个不重复数

如何在不重复给定范围的情况下打印所有可能的变化?