What is the fastest way to decide whether a number is a square number in Python 3
我正试图根据列表中的数字是否为平方数返回真/假输出。
需要对列表进行多次检查,列表可以是任何正整数,这意味着整数可能非常大,事实上,对于使用其他涉及math.sqrt()函数的解决方案来说,它会产生溢出错误,如下所示:
1 2 3 4 5 6 | userList = [1*10**1000] print ([x for x in userList if math.sqrt(x).is_integer()]) >>>Traceback (most recent call last): print ([x for x in userList if math.sqrt(x).is_integer()]) OverflowError: int too large to convert to float |
以下是我的*方法:
1 2 3 4 5 6 | def squares(): for i in userList: if i in squares: #the list in which all the square numbers are stored return True else: return False |
*我目前的想法是将平方数预先准备成一个单独的列表,以便进行比较,但我正在寻找一种替代方法,因为用户列表可能变得非常大,速度更快。
我希望将返回的输出存储在一个单独的列表中,如下所示:
1 2 3 4 5 6 | out = [] for i in userList: out.append(squares()) print(out) >>>[False,True...] |
正如你所看到的,处理许多数字需要很长时间,这就是为什么我需要更快的方法的原因。
一个简单的方法是编写一个整数平方根函数。下面是一种基于二进制搜索的次优(但仍然相当快)方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def is_sqrt(m,n): return m**2 <= n < (m+1)**2 def isqrt(n): low = 0 high = n m = (low + high)//2 while not is_sqrt(m,n): if m**2 < n: #too small! must be in [m+1,high] low = m+1 else: #too big! must be in [low, m-1] high = m - 1 m = (low + high) // 2 return m def is_square(n): return n == (isqrt(n))**2 |
然后,以下几乎是即时的:
1 2 3 4 | >>> is_square(77**200) True >>> is_square(77**200 + 1) False |