将一个数字的位数相加
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。以上是关于将一个数字的位数相加的主要内容,如果未能解决你的问题,请参考以下文章