将一个数字的位数相加

Posted

技术标签:

【中文标题】将一个数字的位数相加【英文标题】:Sum the digits of a number 【发布时间】:2013-02-03 02:22:48 【问题描述】:

如果我想找到一个数字的数字之和,即:

输入:932 输出:14,即(9 + 3 + 2)

最快的方法是什么?

我本能地这样做了:

sum(int(digit) for digit in str(number))

我在网上找到了这个:

sum(map(int, str(number)))

哪种方法最适合速度,还有其他更快的方法吗?

【问题讨论】:

这些都很好并且等效。 map 快一点。 你可以做x % 9,看这篇文章:sjsu.edu/faculty/watkins/Digitsum0.htm 【参考方案1】:
def digits_sum(a):
    sum = 0
    for i in range(len(str(a))):
        sum += a // 10 ** i % 10
    return sum

【讨论】:

虽然可能是正确的,但这个解决方案对我来说似乎效率低下,对每个数字执行除法、指数和模运算。您是否已计时并将速度与此处的其他答案进行比较?这很重要,因为问题主要是关于各种解决方案的速度。【参考方案2】:

这是我自己做的,它可以在没有任何 BigInt 库的情况下正确处理任意精度整数:

function sumdigits(x,k,z)

    gsub(/[^1-9]+/,"",x)    # throw away junk, and all 0's
    z += gsub(++k, "",x)    # get rid of all the 1's

    while ( x!="" )   

       # process 2 numbers at a time, so 
       # even in worst case, the while() loop
       # is only called 4 cycles, while offering 
       # rapid early-exit.
 
       z +=  (++k * gsub(k,"",x))+\
             (++k * gsub(k,"",x)) ;
    
    return z 

为了好玩,我随机生成了 3 个综合大整数,每个整数都有 46,539,361 十进制数字,每个数字的总和都超过 2 亿

214,942,897 217,165,213 223,275,043

在我 2018 年的系统上,它平均约为 1.75 秒左右。

对于较小的输入:

0.807 秒 23,019,933-digit 长整数总和为 102,221,680 2,829,207-digit 长整数加起来为 13,258,766 为 0.109 秒

【讨论】:

【参考方案3】:

做一些 Codecademy 挑战我解决了这个问题:

def digit_sum(n):
    digits = []
    nstr = str(n)
    for x in nstr:
        digits.append(int(x))
    return sum(digits)

【讨论】:

【参考方案4】:

一个以 10 为底的数可以表示为一系列形式

a × 10^p + b × 10^p-1 .. z × 10^0

所以一个数的位数之和就是各项系数之和。

根据这些信息,可以这样计算数字的总和:

import math

def add_digits(n):
    # Assume n >= 0, else we should take abs(n)
    if 0 <= n < 10:
        return n
    r = 0
    ndigits = int(math.log10(n))
    for p in range(ndigits, -1, -1):
        d, n = divmod(n, 10 ** p)
        r += d
    return r

这实际上是已接受答案中连续除以 10 的逆过程。鉴于与公认答案相比,此函数中的额外计算,发现此方法相比之下表现不佳也就不足为奇了:它慢了大约 3.5 倍,大约慢了 2 倍

sum(int(x) for x in str(n))

【讨论】:

【参考方案5】:

它只适用于三位数字,但它有效

a = int(input())
print(a // 100 + a // 10 % 10 + a % 10)

【讨论】:

【参考方案6】:

最好的方法是使用数学。 我从学校就知道这一点。(也来自代码战)

def digital_sum(num):
    return (num % 9) or num and 9

只是不知道这在代码中是如何工作的,但我知道这是数学

如果一个数能被 9 整除,那么它的 digital_sum 将为 9, 如果不是这样,那么num % 9 将是数字总和。

【讨论】:

查看this comment中的链接以获得解释。【参考方案7】:

在一个解决问题的挑战网站上找到了这个。不是我的,但它有效。

num = 0            # replace 0 with whatever number you want to sum up
print(sum([int(k) for k in str(num)]))

【讨论】:

【参考方案8】:

你发布的两行都很好,但你可以纯粹用整数来做,这将是最有效的:

def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

divmod:

def sum_digits2(n):
    s = 0
    while n:
        n, remainder = divmod(n, 10)
        s += remainder
    return s

没有增加分配的版本更快:

def sum_digits3(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

> %timeit sum_digits(n)
1000000 loops, best of 3: 574 ns per loop

> %timeit sum_digits2(n)
1000000 loops, best of 3: 716 ns per loop

> %timeit sum_digits3(n)
1000000 loops, best of 3: 479 ns per loop

> %timeit sum(map(int, str(n)))
1000000 loops, best of 3: 1.42 us per loop

> %timeit sum([int(digit) for digit in str(n)])
100000 loops, best of 3: 1.52 us per loop

> %timeit sum(int(digit) for digit in str(n))
100000 loops, best of 3: 2.04 us per loop

【讨论】:

sum_digits3() 应该使用// 而不是/,对吧?否则我会得到错误的答案。 我需要在这里解释一下“while n:”吗?我不知道 Python 如何理解何时停止。例如,324 的位数之和应该是 3+2+4。对于最后一个(前面的数字三),在while循环中,3/10=0,然后它变成“while 0:”。那么,while 0 对循环是否意味着 False,然后转义循环并返回 s? 是的,有些东西在需要布尔值的地方等同于 False。见这里:docs.python.org/2/library/stdtypes.html#truth-value-testing 有没有办法通过公式找到奇数序列的位数之和? 您的 %timeit 调用中n 的值是多少?【参考方案9】:

这是一个没有任何循环或递归但仅适用于非负整数的解决方案(Python3):

def sum_digits(n):
    if n > 0:
        s = (n-1) // 9    
        return n-9*s
    return 0

【讨论】:

【参考方案10】:

我想出了一个递归解决方案:

def sumDigits(num):
#   print "evaluating:", num
  if num < 10:
    return num

  # solution 1
#   res = num/10
#   rem = num%10
#   print "res:", res, "rem:", rem
#   return sumDigits(res+rem)

    # solution 2
  arr = [int(i) for i in str(num)]
  return sumDigits(sum(arr))

# print(sumDigits(1))
# print(sumDigits(49))
print(sumDigits(439230))
# print(sumDigits(439237))

【讨论】:

【参考方案11】:

试试这个

    print(sum(list(map(int,input("Enter your number ")))))

【讨论】:

【参考方案12】:
reduce(op.add,map(int,list(str(number))))

测试:

from datetime import datetime
number=49263985629356279356927356923569976549123548126856926293658923658923658923658972365297865987236523786598236592386592386589236592365293865923876592385623987659238756239875692387659238756239875692856239856238563286598237592875498259826592356923659283756982375692835692385653418923564912354687123548712354827354827354823548723548235482735482354827354823548235482354823548235482735482735482735482354823548235489235648293548235492185348235481235482354823548235482354823548235482354823548234



startTime = datetime.now()

for _ in  range(0,100000) :
    out=reduce(op.add,map(int,list(str(number))))

now=datetime.now()
runningTime=(now - startTime)

print ("Running time:%s" % runningTime)
print(out)

运行时间:0:00:13.122560 2462

【讨论】:

【参考方案13】:

你也可以尝试使用名为 divmod() 的内置函数;

number = int(input('enter any integer: = '))
sum = 0
while number!=0: 
    take = divmod(number, 10) 
    dig = take[1] 
    sum += dig 
    number = take[0] 
print(sum) 

你可以取任意位数

【讨论】:

【参考方案14】:
def sumOfDigits():

    n=int(input("enter digit:")) 
    sum=0
    while n!=0 :

        m=n%10
        n=n/10
        sum=int(sum+m)

    print(sum)

sumOfDigits()

【讨论】:

您好!欢迎来到本站!虽然您的答案似乎是问题的有效解决方案,但它并没有回答问题本身:“哪个更快?”鉴于这是一个速度问题,您能否将您的解决方案的测试结果与给出的示例进行对比?【参考方案15】:

你可以试试这个

def sumDigits(number):
    sum = 0
    while(number>0):
        lastdigit = number%10
        sum += lastdigit
        number = number//10

    return sum

【讨论】:

【参考方案16】:
num = 123
dig = 0
sum = 0
while(num > 0):
  dig = int(num%10)
  sum = sum+dig
  num = num/10

print(sum) // 确保在此行上方添加空格

【讨论】:

num 不小于 0。什么都不会发生。让它大于,这可以工作。 是的..错误地小于。现在它大于并且工作正常【参考方案17】:
def digitsum(n):
    result = 0
    for i in range(len(str(n))):
        result = result + int(str(n)[i:i+1])
    return(result)

“结果”初始化为 0。

在for循环中,数字(n)被转换成一个字符串,用循环索引(i)分割并得到每个数字。 ---> str(n)[i:i+1]

这个切片的数字被转换回一个整数----> int(str(n)[i:i+1])

因此添加到结果中。

【讨论】:

请添加几句话来解释您的代码以及它如何解决问题。【参考方案18】:
n = str(input("Enter the number\n"))

list1 = []

for each_number in n:

        list1.append(int(each_number))

print(sum(list1))

【讨论】:

请使用edit链接来解释这段代码是如何工作的,不要只给出代码,因为解释更有可能帮助未来的读者。另见How to Answer。 source 这不能回答问题。【参考方案19】:

如果您想继续对数字求和,直到获得 个位数(我最喜欢的可被 9 整除的数字之一),您可以这样做:

def digital_root(n):
    x = sum(int(digit) for digit in str(n))
    if x < 10:
        return x
    else:
        return digital_root(x)

这实际上本身就相当快......

%timeit digital_root(12312658419614961365)

10000 loops, best of 3: 22.6 µs per loop

【讨论】:

聪明的,把函数折叠起来! 递归! @vashts85 我也是,能被9整除是什么? 对于数字根(以 10 为基数),有一个直接公式:digital_root(n) = n-9*(n-1//9) 对数字求和,直到得到一位数,可以直接使用 Modular 9 算术:(n - 1) % 9 + 1【参考方案20】:

这可能会有所帮助

def digit_sum(n):
    num_str = str(n)
    sum = 0
    for i in range(0, len(num_str)):
        sum += int(num_str[i])
    return sum

【讨论】:

谢谢,这个帮助我解决了这个问题:检查给定的数字是否可以在对数字求和后给出模 0。

以上是关于将一个数字的位数相加的主要内容,如果未能解决你的问题,请参考以下文章

给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

LeetCode——258. 各位相加(Java)

各位相加

各位相加

关于double类型数字相加位数发生变化的问题

Python笔试题:给定一个非负整数num,反复将各个位上的数字相加,直到结果为一位数杭州多测师杭州多测师_王sir