[英]Sum the digits of a number
如果我想找到一个数字的数字总和,即:
932
14
,即(9 + 3 + 2)
最快的方法是什么?
我本能地做了:
sum(int(digit) for digit in str(number))
我在网上找到了这个:
sum(map(int, str(number)))
哪种方法最适合提高速度,还有其他更快的方法吗?
你发布的两行都很好,但你可以纯粹用整数来做,这将是最有效的:
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
如果你想继续对数字求和,直到得到一个位数(我最喜欢的数字可以被 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
这可能会有所帮助
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
在解决问题的挑战网站之一上找到了这个。 不是我的,但它有效。
num = 0 # replace 0 with whatever number you want to sum up
print(sum([int(k) for k in str(num)]))
做一些 Codecademy 挑战我解决了这个问题:
def digit_sum(n):
digits = []
nstr = str(n)
for x in nstr:
digits.append(int(x))
return sum(digits)
编辑:答案不适合这个问题。
问题是将数字的所有数字相加并返回。
我的回答是将数字的所有数字相加,直到达到一位数。
编辑结束最好的方法是使用数学。
我从学校知道这一点。(有点也来自代码战)
def digital_sum(num):
return (num % 9) or num and 9
只是不知道这在代码中是如何工作的,但我知道这是数学
如果一个数可以被 9 整除,那么它的 digital_sum 将是 9,
如果不是这种情况,那么num % 9
将是数字总和。
您还可以使用以下命令:
def sum_digits(num):
num = str(num)
digitSum = 0
for i in num:
digitSum += int(i)
return digitSum
print sum_digits(875)
尝试这个
print(sum(list(map(int,input("Enter your number ")))))
def digitsum(n):
result = 0
for i in range(len(str(n))):
result = result + int(str(n)[i:i+1])
return(result)
“结果”初始化为 0。
在 for 循环中,number(n) 被转换成一个字符串,用循环 index(i) 分割并得到每个数字。 ---> str (n)[ i:i+1 ]
这个切片后的数字被转换回整数----> int (str(n)[i:i+1])
因此添加到结果中。
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()
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
我想出了一个递归解决方案:
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))
这是一个没有任何循环或递归但仅适用于非负整数的解决方案(Python3):
def sum_digits(n):
if n > 0:
s = (n-1) // 9
return n-9*s
return 0
一个以 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 倍,大约慢了两倍
sum(int(x) for x in str(n))
这就是我自己做的,它可以在没有任何 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
0.109秒为2,829,207-digit
长整型总结到13,258,766
def digits_sum(a):
sum = 0
for i in range(len(str(a))):
sum += a // 10 ** i % 10
return sum
在这里使用数学或字符串是否更快取决于输入数字的大小。
对于小数,使用数学(除法和模数):
def sum_digits_math(n):
r = 0
while n:
r, n = r + n % 10, n // 10
return r
对于大数,使用字符串域:
def sum_digits_str_dumb(n):
"""from OP https://stackoverflow.com/q/14939953/674039"""
return sum(int(i) for i in str(n))
def sum_digits_str_fast(n):
d = str(n)
return sum(int(s) * d.count(s) for s in "123456789")
使用除法和模数开始失去在字符串域中工作的交叉点位于大约 27 位长的数字处(蓝线与下图中的红线相交):
随着输入数字越大,使用数学的性能配置文件越差,但字符串域似乎在输入长度上线性缩放。 用于生成这些图表的代码 在这里,我在 macOS 上使用 CPython 3.10.2。
为什么评分最高的答案比这慢3.70 倍?
% echo; ( time (nice echo 33785139853861968123689586196851968365819658395186596815968159826259681256852169852986 \
| mawk2 'gsub(//,($_)($_)($_))+gsub(//,($_))+1' | pvE0 \
| mawk2 '
function __(_,___,____,_____) {
____=gsub("[^1-9]+","",_)~""
___=10
while((+____<--___) && _) {
_____+=___*gsub(___,"",_)
}
return _____+length(_) }
BEGIN { FS=OFS=ORS
RS="^$"
} END {
print __($!_) }' )| pvE9 ) | gcat -n | lgp3 ;
in0: 173MiB 0:00:00 [1.69GiB/s] [1.69GiB/s] [<=> ]
out9: 11.0 B 0:00:09 [1.15 B/s] [1.15 B/s] [<=> ]
in0: 484MiB 0:00:00 [2.29GiB/s] [2.29GiB/s] [ <=> ]
( nice echo | mawk2 'gsub(//,($_)($_)($_))+gsub(//,($_))+1' | pvE 0.1 in0 | )
8.52s user 1.10s system 100% cpu 9.576 total
1 2822068024
% echo; ( time ( nice echo 33785139853861968123689586196851968365819658395186596815968159826259681256852169852986 \
\
| mawk2 'gsub(//,($_)($_)($_))+gsub(//,($_))+1' | pvE0 \
| gtr -d '\n' \
\
| python3 -c 'import math, os, sys;
[ print(sum(int(digit) for digit in str(ln)), \
end="\n") \
\
for ln in sys.stdin ]' )| pvE9 ) | gcat -n | lgp3 ;
in0: 484MiB 0:00:00 [ 958MiB/s] [ 958MiB/s] [ <=> ]
out9: 11.0 B 0:00:35 [ 317miB/s] [ 317miB/s] [<=> ]
( nice echo | mawk2 'gsub(//,($_)($_)($_))+gsub(//,($_))+1' | pvE 0.1 in0 | )
35.22s user 0.62s system 101% cpu 35.447 total
1 2822068024
这已经有点大方了。 在这个 2.82 GB 的大型综合测试用例中,它慢了 19.2 倍。
% echo; ( time ( pvE0 < testcases_more108.txt | mawk2 'function __(_,___,____,_____) { ____=gsub("[^1-9]+","",_)~"";___=10; while((+____<--___) && _) { _____+=___*gsub(___,"",_) }; return _____+length(_) } BEGIN { FS=RS="^$"; CONVFMT=OFMT="%.20g" } END { print __($_) }' ) | pvE9 ) |gcat -n | ggXy3 | lgp3;
in0: 284MiB 0:00:00 [2.77GiB/s] [2.77GiB/s] [=> ] 9% ETA 0:00:00
out9: 11.0 B 0:00:11 [1016miB/s] [1016miB/s] [<=> ]
in0: 2.82GiB 0:00:00 [2.93GiB/s] [2.93GiB/s] [=============================>] 100%
( pvE 0.1 in0 < testcases_more108.txt | mawk2 ; )
8.75s user 2.36s system 100% cpu 11.100 total
1 3031397722
% echo; ( time ( pvE0 < testcases_more108.txt | gtr -d '\n' | python3 -c 'import sys; [ print(sum(int(_) for _ in str(__))) for __ in sys.stdin ]' ) | pvE9 ) |gcat -n | ggXy3 | lgp3;
in0: 2.82GiB 0:00:02 [1.03GiB/s] [1.03GiB/s] [=============================>] 100%
out9: 11.0 B 0:03:32 [53.0miB/s] [53.0miB/s] [<=> ]
( pvE 0.1 in0 < testcases_more108.txt | gtr -d '\n' | python3 -c ; )
211.47s user 3.02s system 100% cpu 3:32.69 total
1 3031397722
—————————————————————
更新:该概念的本机 python3 代码——即使我有可怕的 python 技能,我也看到了 4 倍的加速:
% echo; ( time ( pvE0 < testcases_more108.txt \
\
|python3 -c 'import re, sys;
print(sum([ sum(int(_)*re.subn(_,"",__)[1]
for _ in [r"1",r"2", r"3",r"4",
r"5",r"6",r"7",r"8",r"9"])
for __ in sys.stdin ]))' |pvE9))|gcat -n| ggXy3|lgp3
in0: 1.88MiB 0:00:00 [18.4MiB/s] [18.4MiB/s] [> ] 0% ETA 0:00:00
out9: 0.00 B 0:00:51 [0.00 B/s] [0.00 B/s] [<=> ]
in0: 2.82GiB 0:00:51 [56.6MiB/s] [56.6MiB/s] [=============================>] 100%
out9: 11.0 B 0:00:51 [ 219miB/s] [ 219miB/s] [<=> ]
( pvE 0.1 in0 < testcases_more108.txt | python3 -c | pvE 0.1 out9; )
48.07s user 3.57s system 100% cpu 51.278 total
1 3031397722
即使是较小的测试用例也能实现 1.42 倍的加速:
echo; ( time (nice echo 33785139853861968123689586196851968365819658395186596815968159826259681256852169852986 \
| mawk2 'gsub(//,($_)($_)$_)+gsub(//,$_)+1' ORS='' | pvE0 | python3 -c 'import re, sys; print(sum([ sum(int(_)*re.subn(_,"",__)[1] for _ in [r"1",r"2", r"3",r"4",r"5",r"6",r"7",r"8",r"9"]) for __ in sys.stdin ]))' | pvE9 )) |gcat -n | ggXy3 | lgp3
in0: 484MiB 0:00:00 [2.02GiB/s] [2.02GiB/s] [ <=> ]
out9: 11.0 B 0:00:24 [ 451miB/s] [ 451miB/s] [<=> ]
( nice echo | mawk2 'gsub(//,($_)($_)$_)+gsub(//,$_)+1' ORS='' | pvE 0.1 in0)
20.04s user 5.10s system 100% cpu 24.988 total
1 2822068024
num = 123
dig = 0
sum = 0
while(num > 0):
dig = int(num%10)
sum = sum+dig
num = num/10
print(sum) // 确保在此行上方添加空格
你可以试试这个
def sumDigits(number):
sum = 0
while(number>0):
lastdigit = number%10
sum += lastdigit
number = number//10
return sum
您也可以使用名为 divmod() 的 built_in_function 尝试此操作;
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)
你可以取任意位数
这是我找到的最佳解决方案:
function digitsum(n) {
n = n.toString();
let result = 0;
for (let i = 0; i < n.length; i++) {
result += parseInt(n[i]);
}
return result;
}
console.log(digitsum(192));
它只适用于三位数,但它有效
a = int(input())
print(a // 100 + a // 10 % 10 + a % 10)
n = str(input("Enter the number\n"))
list1 = []
for each_number in n:
list1.append(int(each_number))
print(sum(list1))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.