有没有办法找到下一个完美的正方形?

Posted

技术标签:

【中文标题】有没有办法找到下一个完美的正方形?【英文标题】:Is there a way to find the next perfect square? 【发布时间】:2021-01-26 13:14:34 【问题描述】:

这是我的代码,但是它只返回下一个数字(例如,取 121 它返回 122 而不是 144),但我不明白为什么。

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    if math.sqrt(sq).is_integer:
        sqnext = sq + 1
        if math.sqrt(sqnext).is_integer:
            return sqnext
    else:
        return -1

【问题讨论】:

.is_integer 是一种方法,但您没有调用它。 math.sqrt(sq).is_integer() 测试从 sqrt 返回的值是否为整数,而 math.sqrt(sq).is_integer 是一个内置方法对象,在 if 语句中始终被认为是 True。 (你的逻辑也错了) 4 是 2 的平方。为什么你会认为下一个平方不是 5 或者什么都没有? (如果sq是一个正方形,可以写成x * x。下一个大于sq的正方形是(x + 1) * (x + 1),不是sq+1,不需要测试)。 请注意,math.sqrt(sq).is_integer() 是一种测试数字是否为正方形的有缺陷的方法。它对于负数(引发异常)和四舍五入(或作为双精度数的不可表达性)导致麻烦的大数失败。 【参考方案1】:

你的逻辑不正确。使用sqnext = sq + 1,您计算的是下一个数字,而不是下一个平方。

试试这个:

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    if math.sqrt(sq).is_integer:
        sqnext = math.sqrt(sq) + 1
        return sqnext * sqnext
    else:
        return -1
        
print(find_next_square(121))    

编辑

看起来is_integer 方法存在缺陷,并给出了亨利指出的错误值。以下代码适用于不超过一定限制的正整数。

import math
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise   
    if int(math.sqrt(sq))**2 == sq:
        sqnext = math.sqrt(sq)
        return sqnext * sqnext
    else:
        return -1

print(find_next_square(5))
print(find_next_square(121))

进一步由于sqrt不适用于负数,需要单独处理:

import math
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    sign = -1 if sq < 0 else 1

    if int(math.sqrt(abs(sq)))**2 == abs(sq):
        sqnext = math.sqrt(abs(sq)) + sign * 1
        return sqnext * sqnext * sign
    else:
        return -1
        
print(find_next_square(5))
print(find_next_square(121))
print(find_next_square(-9))

此外,由于溢出问题,上述所有方法都不适用于超出限制的大量数据。

【讨论】:

你能在 -1、5 和 (10 ** 10000) 上测试你的代码吗?结果应该是 -1,-1,(一些很大的数字)。【参考方案2】:

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    if math.sqrt(sq).is_integer:
      sqnext = math.sqrt(sq) + 1
      if math.sqrt(sqnext).is_integer:
        return int(sqnext * sqnext)
    else:
        return -1

sqnext = sq + 1 这是你错的地方。您应该返回 math.sqrt(sq) + 1 而不是 sq + 1

输出

find_next_square(144)
>>> 169

【讨论】:

【参考方案3】:

sqnext = sq + 1 中,您将前一个数字的平方加 1 并将其分配给 sqnext

应该是sqnext = (math.sqrt(sq)+1)**2

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    if math.sqrt(sq).is_integer:
        sqnext = (math.sqrt(sq)+1)**2
        return sqnext
    else:
        return -1

【讨论】:

【参考方案4】:

is_integer 是一个函数而不是变量,要调用它,您需要像调用任何函数一样使用 '()'

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    if math.sqrt(sq).is_integer():
        sqnext = sq + 1
        if math.sqrt(sqnext).is_integer():
            return sqnext
    else:
        return -1

尽管如此,您仍将只检查以下数量的sq,而不是下一个方块。你想增加sq 的平方根,然后返回它的平方。

import math 
def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    found_sqrt = math.sqrt(sq)
    if found_sqrt.is_integer():
        sqrt_incr = found_sqrt + 1
        return sqrt_incr * sqrt_incr
    else:
        return -1

就像其他答案所说,在你得到sq 的平方根并且它确实是一个整数后,你加 1 然后返回它的平方,从而得到下一个完美的平方。

【讨论】:

以上是关于有没有办法找到下一个完美的正方形?的主要内容,如果未能解决你的问题,请参考以下文章

在字符串中找到完美的正方形

找到大约 300 位排列的所有完美正方形

在两个数组中找到对,使得当相乘时变成一个完美的正方形

Python - 在给定的大数范围内找到所有完美正方形的最快方法

完美正方形-深度遍历

如何在不使用 sqrt 的情况下检查整数是不是是完美的正方形 [重复]