簡體   English   中英

查找整個序列的數字總和的有效方法

[英]Efficient way to find sum of digits of an entire sequence

在下面的代碼片段中,我找到了區間[a,b]之間所有奇數的位數之和

def SumOfDigits(a, b):
    s = 0
    if a%2 == 0:
        a+=1
    if b%2 == 0:
        b-=1   
    for k in range(a,b+1,2):
        s+= sum(int(i) for i in list(str(k)))
    return s

有沒有一種有效的方法來實現同樣的目標? 任何圖案,這導致明確的公式。

我在https://oeis.org上搜索過

避免轉換到字符串和從字符串轉換的所有開銷,並直接使用數字本身:

def SumOfDigits(a, b):
    result = 0
    for i in range(a + (not a % 2), b + 1, 2):
        while i:
            result += i % 10
            i //= 10
    return result

當然有一種模式。 讓我們來看看總結ab之間所有奇數和偶數的數字的問題。

例如:17到33

17  18  19    20  21  22  23  24  25  26  27  28  29    30  31  32  33

中間部分為您提供從0到9(45)加10次的所有數字的總和2.左側部分是7 + 8 + 9加3次1,右側是0 + 1 + 2 + 3加4的總和次3。

中間部分可以包含幾個十個塊,例如,如果你計算17到63之間的范圍,你可以得到40倍45加10個simes,其中digitums從2到5。

這給你一個遞歸算法:

def ssum(n):
    return n * (n + 1) // 2

def dsum(a, b):
    res = 0

    if a == b:
        while a:
            res += a % 10
            a //= 10

    elif a < b:
        aa = a // 10
        bb = b // 10

        ra = a % 10
        rb = b % 10

        if aa == bb:
            res += ssum(rb) - ssum(ra - 1)
            res += (rb - ra + 1) * dsum(aa, bb)

        else:
            if ra > 0:
                res += 45 - ssum(ra - 1)
                res += (10 - ra) * dsum(aa, aa)
                aa += 1

            if rb < 9:
                res += ssum(rb)
                res += (rb + 1) * dsum(bb, bb)
                bb -= 1

            if aa <= bb:
                res += 45 * (bb - aa + 1)
                res += 10 * dsum(aa, bb) 

    return res

現在讓我們將其擴展為僅包含奇數。 Adkust a ,它是偶數和b所以它是奇怪的。 你的數字和的總和現在在偶數和奇數對上運行,其中even + 1 == odd 這意味着奇數的數字id比偶數更多,因為除了最后的數字之外的所有數字都是相同的,並且最后的奇數數字比偶數數字多一個。

因此:

dsum(a, b) == oddsum + evensum

和:

oddsum - evensum == (b - a + 1) // 2

然后,將所有奇數的位數相加的函數為:

def oddsum(a, b):
    if a % 2: a -= 1
    if b % 2 == 0: b -= 1

    d = (b - a + 1) // 2

    return (dsum(a, b) + d) // 2

當我查看你關於OEIS的評論時,我注意到可以通過編寫一個函數來簡化算法,將所有數字中的數字從0加到n ,然后計算差值dsum(b) - dsum(a) 可能有更多的優化機會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM