两种判断Armstrong数的Python实现:哪种方法更优、复杂度更低?
阿姆斯特朗数两种实现的对比分析
咱们来拆解这两个判断阿姆斯特朗数的实现,聊聊哪个更优、复杂度更低~
首先明确核心定义:阿姆斯特朗数是指一个n位数,其各位数字的n次方之和等于它本身。两个实现都围绕这个规则展开,但实现路径有所不同:
两种实现的核心逻辑
第一种(数学运算版)
def isArmstrong(n): temp = n length=len(str(n)) sum1,digit=0,0 while n>0: digit = n%10 n = n//10 sum1 += digit**length if sum1==temp: print('Armstrong No') else: print('Not an Armstrong no') isArmstrong(371)
通过取模(n%10)获取最后一位数字,整除(n//10)去掉最后一位,循环遍历每一位并计算幂次和。
第二种(字符串遍历版)
def isArmstrong(n): n=str(n) sum=0 for i in n: sum += int(i)**len(n) if str(sum)==n: #Edited After Reading Comments print('No is Armstrong') else: print('No is not Armstrong') isArmstrong(371)
把数字转为字符串,直接遍历每个字符(对应每一位数字),转成整数后计算幂次和,最后对比结果。
复杂度与优劣对比
时间复杂度
两种实现的时间复杂度完全相同,都是O(d)(d为数字的位数):
- 第一种的while循环会执行d次,每次循环做取模、整除和幂运算;
- 第二种的for循环会遍历d个字符,每次做类型转换和幂运算。
幂运算的时间对于固定位数的数字来说可视为常数,所以整体时间复杂度都是线性的,和数字位数成正比。
空间复杂度
- 第一种:仅使用
temp、length、sum1、digit几个变量,额外空间为O(1)(常数级); - 第二种:需要把数字转为字符串存储,字符串长度等于数字位数d,额外空间为O(d)。
从空间效率来看,第一种实现更优。
可读性与代码简洁性
第二种实现的逻辑更直观,代码更简洁:转成字符串后直接遍历每一位,不需要理解取模、整除的数学拆分逻辑,新手更容易看懂。第一种需要对数字的数学操作有一定理解,相对稍显繁琐。
边界情况处理
- 第一种可以正确处理负数:输入负数时,
n>0不成立,循环不执行,sum1为0,与原负数不等,会输出正确的"Not an Armstrong no"; - 第二种处理负数会报错:负数转字符串后包含负号
-,遍历到负号时int(i)会抛出ValueError,无法正确处理非正整数的情况。
总结
- 若优先考虑空间效率,第一种实现更优;
- 若优先考虑代码可读性和简洁性,第二种更合适(但需要额外处理负数等边界场景);
- 两者的时间复杂度没有差异。
内容的提问来源于stack exchange,提问作者Saransh Khurana
相关产品推荐
相关产品推荐

