当 Python 中的输入是大数时,如何有效地在一个范围内找到完美的正方形

Posted

技术标签:

【中文标题】当 Python 中的输入是大数时,如何有效地在一个范围内找到完美的正方形【英文标题】:How to find perfect squares in a range efficiently when the inputs are large numbers in Python 【发布时间】:2015-01-10 03:29:39 【问题描述】:

问题是当输入非常大的数字时,如何有效地找到给定范围内的完美平方。我的解决方案是给出Time Limit Exceeded 错误。我已经检查了以下链接,但它们并没有解决我的问题: - Python Program on Perfect Squares - How could I check if a number is a perfect square? - Fastest way to determine if an integer's square root is an integer(我不知道如何在 Python 中实现此链接中给出的解决方案)。

问题题是:

输入格式:第一行包含 T,测试用例的数量。接下来是 T 个测试用例,每个用例换行。每个测试用例包含两个用空格分隔的整数,分别表示 A 和 B。找出范围 A 和 B(均包含)内的所有完美正方形。

输入示例:

2 3 9 17 24

我写的代码是:

import math
def is_perfect_square(n):
    return n % n**0.5 == 0

t = int(raw_input())
for i in range(t):
    numbers = map(int, raw_input().split())
    count = 0
    for j in xrange(numbers[0], numbers[1] + 1): # I also tried range() which gave memory error
        if (is_perfect_square(j)):
            count = count + 1

    print count

虽然此代码适用于较小的数字,但它会为较大的输入提供 Time limit exceeded 错误。

(注意:gmpy 不是一个选项,因为代码必须在没有 gmpy 模块的在线编译器上运行)

【问题讨论】:

【参考方案1】:

与其从A 循环到B 并检查完美的平方,不如直接遍历从sqrt(A)sqrt(B) 的整数并平方,给你答案。

例如,让我们找出 1000 到 2000 之间的平方数:

sqrt(1000) = 31.6  -->  32  (need the ceiling here)
sqrt(2000) = 44.7  -->  44  (need the floor here)

因此,我们的答案是:

322 = 1024 332 = 1089 342 = 1156 352 = 1225 362 = 1296 372 = 1369 382 = 1444 392 = 1521 402 = 1600 412 = 1681 422 = 1764 432 = 1849 442 = 1936

【讨论】:

您已颠倒了您的 floorceiling。并且您需要小心在 sqrt 结果中进行四舍五入。 @MarkRansom 谢谢,我已经纠正了地板/天花板的混淆。 这里你会得到错误:>>> math.ceil(math.sqrt(17)) 5.0 >>> math.floor(math.sqrt(24)) 4.0 . 那行得通。我只需要该范围内的完美正方形的数量,因此通过找到a = int(math.ceil(math.sqrt(x)))b = int(math.floor(math.sqrt(x))) 然后print (b + 1) - a 完成了这项工作。【参考方案2】:

这是我尝试过的:

>>> def isperferct_square(n):
...     return int(math.sqrt(n))*int(math.sqrt(n)) == n
... 
>>> isperferct_square(10)
False
>>> isperferct_square(9)
True
>>> isperferct_square(10000000000000000000)
False
>>> isperferct_square(112312424354957359732985732897583297592735932)
False
>>> isperferct_square(10000000000)
True
>>> 

【讨论】:

【参考方案3】:

您的代码中有几个错误,例如 numbers = map(int, raw_input().split()) 必须在循环之外。与计数器 = 0 相同。无论如何,这里有一个代码,它应该适用于非常高的整数:

t = map(int,raw_input().split())

def is_perfect_square(x):
    if x < 0:
        raise ValueError('square root not defined for negative numbers')
    n = int(x)
    if n == 0:
        return False
    a, b = divmod(n.bit_length(), 2)
    x = 2**(a+b)
    while True:
        y = (x + n//x)//2
        if y >= x:
            return x
        x = y

count = 0
for i in t:
    if is_perfect_square(i)**2 == i:
        count+=1

print count

【讨论】:

以上是关于当 Python 中的输入是大数时,如何有效地在一个范围内找到完美的正方形的主要内容,如果未能解决你的问题,请参考以下文章

通过多列中的值有效地在R中闪烁过滤数据帧

算法:平衡树求第k大数 Sm 前段时间刚学会了用快速排序来求一个列中的第 k大数,可是她觉得每次 序列被改变

如何在python大数计算中抑制科学计数法

如何在Python中优化计算大数

当用户点击第 11 个号码时,如何验证输入文本(在 html 中)是不是是有效的电话号码?

Java中的大数