Python - Проверьте, является ли число квадратом
Я написал функцию, которая возвращает, является ли ввод числа квадратом или нет
def is_square(n):
if n<1:
return False
else:
for i in range(int(n/2)+1):
if (i*i)==n:
return True
else:
return False
Я уверен, что этот код работает. Но когда я сделал тестовые примеры, пример:test.expect( is_square( 4))
, это говорит о том, что значение не то, что ожидалось.
14 ответов
Ваша функция на самом деле не работает, так как она немедленно вернет False при первом найденном неквадратном корне. Вместо этого вы захотите изменить свой код так:
def is_square(n):
if n<1:
return False
else:
for i in range(int(n/2)+1):
if (i*i)==n:
return True
return False
так что он возвращает false только после того, как все возможные квадратные корни были проверены. Вы также можете посмотреть в math.sqrt()
а также float.is_integer()
, Используя эти методы, ваша функция станет такой:
from math import sqrt
def is_square(n):
return sqrt(n).is_integer()
Имейте в виду, что этот метод не будет работать с очень большими числами, но ваш метод будет очень медленным с ними, поэтому вам придется выбирать, какой использовать. Надеюсь, я помог!
Чтобы придерживаться целочисленных алгоритмов, вы можете взглянуть на реализацию двоичного поиска для нахождения квадратного корня:
def is_square(n):
if n < 0:
return False
if n == 0:
return True
x, y = 1, n
while x + 1 < y:
mid = (x+y)//2
if mid**2 < n:
x = mid
else:
y = mid
return n == x**2 or n == (x+1)**2
Основная идея философии Python - написать простой код. Чтобы проверить, является ли число идеальным квадратом:
def is_square(n):
return n**0.5 == int(n**0.5)
При включении поплавка вы можете найти корень числа.
В Python 3.8+ используйте это:
def is_square(n):
root = math.isqrt(n)
return n == root * root
Вы можете просто использовать simpy module import it as,
from sympy.ntheory.primetest import is_square
и вы можете проверить такой номер:
is_square(number)
Он вернет логическое значение
Я думаю, что лучше всего использовать только «встроенную» целочисленную арифметику:
def issquare(n): return math.isqrt(n)**2==n
(Квадраты x**2 априори вычисляются более эффективно, чем произведения x*x...)
Согласно моим таймингам, это (по крайней мере, до ~ 10 ^ 8) быстрее, чем
sympy.numtheory.primetest.is_square
.
(Я использую другое имя, чтобы было проще сравнивать их.) Последний сначала использует некоторые модульные проверки, которые должны значительно ускорить его, но у него так много накладных расходов на преобразование и тестирование (
int
,
as_int
, квадраты становятся n-ми степенями с n=2, целые числа преобразуются из «маленьких» в целые с множественной точностью и обратно, ...), что все преимущество теряется. После множества тестов он примерно делает вышеописанное, используя ntheory.nthroot, что опять-таки является излишеством: предназначено для любого n-го корня, квадратный корень — это всего лишь один частный случай, и noting оптимизирован для этого случая. Некоторые подпрограммы там даже выполняют очень странные арифметические операции с плавающей запятой, включая умножение на 1.0000000001 и тому подобные ужасы... Однажды я получил следующее ужасное сообщение об ошибке: (исходный вывод имеет полный путь
"C:\Users\Username\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\"
вместо каждого "..." ниже...)
File "...\sympy\ntheory\primetest.py", line 112, in is_square
return integer_nthroot(n, 2)[1]
File "...\sympy\core\power.py", line 86, in integer_nthroot
return _integer_nthroot_python(y, n)
File "...\sympy\core\power.py", line 94, in _integer_nthroot_python
x, rem = mpmath_sqrtrem(y)
File "...\mpmath\libmp\libintmath.py", line 284, in sqrtrem_python
y = isqrt_small_python(x)
File "...\mpmath\libmp\libintmath.py", line 217, in isqrt_small_python
r = int(x**0.5 * 1.00000000000001) + 1
KeyboardInterrupt
Это дает хорошее представление о бездне, в которую
sympy
безнадежно тонет...
Документация: см.
is_square
в Справочнике по классу NtheorySympy
PS: FWIW, относительно других ответов, предлагающих использовать
round()
и т. д., позвольте мне просто упомянуть здесь, что
ceil(sqrt(n))**2 < n
(!!), например, когда n является 26-м и 27-м первичными числами - не очень большие числа! Итак, очевидно, использование
math.sqrt
не является адекватным.
Ваш код не работает. Исследуйте это:
>>> is_square(4)
False
>>> range(int(4/2)+1)
[0, 1, 2]
>>> (0*0)==4
False
Предполагая, что n >= 0:
def is_square(n):
tmp = int(n ** 0.5)
return n == tmp * tmp
print(is_square(81), is_square(67108864 ** 2 + 1)) # True False
Другой подход:
def SQRT(x):
import math
if math.sqrt(x) == round(math.sqrt(x)):
return True
else:
return False
def is_square(n):
if n< 0:
return False
return round(n ** 0.5) ** 2 == n
def myfunct(num):
for i in range(0,num):
if i*i==num:
return 'square'
else:
return 'not square'
Самое простое рабочее решение, но не для больших количеств.
def squaretest(num):
sqlist=[]
i=1
while i**2 <= num:
sqlist.append(i**2)
i+=1
return num in sqlist
Чтобы проверить, является ли число квадратом, вы можете использовать такой код:
import math
number = 16
if math.sqrt(number).is_interger:
print "Square"
else:
print "Not square"
import math
import
с math
модуль.
if math.sqrt(number).is_interger:
проверяет, есть ли квадратный корень number
это целое число. Если так, то это будет print
Square
, В противном случае это будет print
Not square
,
Так как math.sqrt() возвращает число с плавающей запятой, мы можем привести его к строке, отделив ее от "." и проверьте, если часть справа (десятичная дробь) равна 0.
import math
def is_square(n):
x= str(math.sqrt(n)).split(".")[1] #getting the floating part as a string.
return True if(x=="0") else False