Làm cách nào để kiểm tra xem một số có phải là một hình vuông hoàn hảo hay không?
Tốc độ không có gì đáng lo ngại, bây giờ, chỉ cần làm việc.
Câu trả lời:
Vấn đề khi dựa vào bất kỳ phép tính dấu phẩy động nào ( math.sqrt(x)
hoặc x**0.5
) là bạn không thể thực sự chắc chắn rằng nó chính xác (đối với số nguyên đủ lớn x
, nó sẽ không như vậy và thậm chí có thể bị tràn). May mắn thay (nếu ai đó không vội vàng ;-) có nhiều cách tiếp cận số nguyên thuần túy, chẳng hạn như sau ...:
def is_square(apositiveint):
x = apositiveint // 2
seen = set([x])
while x * x != apositiveint:
x = (x + (apositiveint // x)) // 2
if x in seen: return False
seen.add(x)
return True
for i in range(110, 130):
print i, is_square(i)
Gợi ý: nó dựa trên "thuật toán Babylon" cho căn bậc hai, xem wikipedia . Nó không làm việc cho bất kỳ số dương mà bạn có đủ bộ nhớ cho việc tính toán để tiến tới hoàn thành ;-).
Chỉnh sửa : hãy xem một ví dụ ...
x = 12345678987654321234567 ** 2
for i in range(x, x+2):
print i, is_square(i)
bản in này, như mong muốn (và cũng trong một khoảng thời gian hợp lý ;-):
152415789666209426002111556165263283035677489 True
152415789666209426002111556165263283035677490 False
Xin vui lòng, trước khi bạn đưa ra các giải pháp dựa trên dấu chấm kết quả trung gian, chắc chắn rằng họ làm việc một cách chính xác trên ví dụ đơn giản này - nó không phải là khó khăn (bạn chỉ cần một vài kiểm tra thêm trong trường hợp sqrt tính là một off ít), chỉ mất một một chút cẩn thận.
Và sau đó thử x**7
và tìm ra cách thông minh để giải quyết vấn đề bạn sẽ gặp phải,
OverflowError: long int too large to convert to float
tất nhiên bạn sẽ phải ngày càng thông minh hơn khi các con số tiếp tục tăng lên.
Nếu tôi đang vội, tất nhiên, tôi sẽ sử dụng gmpy - nhưng sau đó, tôi rõ ràng là thành kiến ;-).
>>> import gmpy
>>> gmpy.is_square(x**7)
1
>>> gmpy.is_square(x**7 + 1)
0
Vâng, tôi biết, điều đó thật dễ dàng, cảm giác giống như gian lận (một chút cảm giác của tôi đối với Python nói chung ;-) - không thông minh chút nào, chỉ là sự trực tiếp và đơn giản hoàn hảo (và, trong trường hợp gmpy, tốc độ tuyệt đối ; -) ...
set([x])
={x}
set
cần thiết? Không phải Babylon chỉ hội tụ đến int(sqrt(x))
, nơi chúng ta chỉ cần kiểm tra xem prev != next
?
Sử dụng phương pháp Newton để nhanh chóng điền vào căn bậc hai số nguyên gần nhất, sau đó bình phương nó và xem đó có phải là số của bạn không. Xem isqrt .
Python ≥ 3,8 có math.isqrt
. Nếu sử dụng phiên bản Python cũ hơn, hãy tìm cách def isqrt(n)
triển khai "" tại đây .
import math
def is_square(i: int) -> bool:
return i == math.isqrt(i) ** 2
Vì bạn không bao giờ có thể phụ thuộc vào các phép so sánh chính xác khi xử lý các phép tính dấu phẩy động (chẳng hạn như các cách tính căn bậc hai này), việc triển khai ít lỗi hơn sẽ là
import math
def is_square(integer):
root = math.sqrt(integer)
return integer == int(root + 0.5) ** 2
Hãy tưởng tượng integer
là 9
. math.sqrt(9)
có thể là 3.0
, nhưng nó cũng có thể là một cái gì đó giống như 2.99999
hoặc 3.00001
, vì vậy bình phương kết quả ngay lập tức là không đáng tin cậy. Biết rằng int
có giá trị sàn, tăng giá trị float 0.5
trước tiên có nghĩa là chúng ta sẽ nhận được giá trị mà chúng ta đang tìm kiếm nếu chúng ta đang ở trong một phạm vi mà float
vẫn có độ phân giải đủ tốt để đại diện cho các số gần với giá trị mà chúng ta đang tìm kiếm .
if int(root + 0.5) ** 2 == integer:
nếu int
hoạt động như floor
cho những con số chúng ta quan tâm.
math.sqrt(9)
thực sự có thể là 2.99999
? float
Bản đồ của Python với C double
, nhưng tôi nghĩ rằng ngay cả loại FP 16 bit cũng có độ chính xác cao hơn thế, vì vậy có thể nếu bạn có một trình biên dịch C sử dụng FP 8 bit ("minifloats") làm double
loại của nó ? Tôi cho rằng về mặt kỹ thuật thì điều đó có thể xảy ra, nhưng đối với tôi thì có vẻ như đó là trường hợp trên bất kỳ máy tính nào chạy Python hiện nay.
math.sqrt(9)
sẽ trả 2.99999
về trên bất kỳ hệ thống cụ thể nào, nhưng kết quả thực tế phụ thuộc vào hệ thống và không thể mong đợi là chính xác.
Nếu bạn quan tâm, tôi có câu trả lời thuần toán cho một câu hỏi tương tự tại math stackexchange, "Phát hiện hình vuông hoàn hảo nhanh hơn bằng cách trích xuất căn bậc hai" .
Việc triển khai isSquare (n) của riêng tôi có thể không phải là tốt nhất, nhưng tôi thích nó. Tôi đã mất vài tháng nghiên cứu về lý thuyết toán học, tính toán kỹ thuật số và lập trình python, so sánh bản thân với những người đóng góp khác, v.v., để thực sự nhấp vào phương pháp này. Tôi thích sự đơn giản và hiệu quả của nó. Tôi không thấy tốt hơn. Nói cho tôi biết bạn nghĩ gì.
def isSquare(n):
## Trivial checks
if type(n) != int: ## integer
return False
if n < 0: ## positivity
return False
if n == 0: ## 0 pass
return True
## Reduction by powers of 4 with bit-logic
while n&3 == 0:
n=n>>2
## Simple bit-logic test. All perfect squares, in binary,
## end in 001, when powers of 4 are factored out.
if n&7 != 1:
return False
if n==1:
return True ## is power of 4, or even power of 2
## Simple modulo equivalency test
c = n%10
if c in {3, 7}:
return False ## Not 1,4,5,6,9 in mod 10
if n % 7 in {3, 5, 6}:
return False ## Not 1,2,4 mod 7
if n % 9 in {2,3,5,6,8}:
return False
if n % 13 in {2,5,6,7,8,11}:
return False
## Other patterns
if c == 5: ## if it ends in a 5
if (n//10)%10 != 2:
return False ## then it must end in 25
if (n//100)%10 not in {0,2,6}:
return False ## and in 025, 225, or 625
if (n//100)%10 == 6:
if (n//1000)%10 not in {0,5}:
return False ## that is, 0625 or 5625
else:
if (n//10)%4 != 0:
return False ## (4k)*10 + (1,9)
## Babylonian Algorithm. Finding the integer square root.
## Root extraction.
s = (len(str(n))-1) // 2
x = (10**s) * 4
A = {x, n}
while x * x != n:
x = (x + (n // x)) >> 1
if x in A:
return False
A.add(x)
return True
Khá thẳng về phía trước. Đầu tiên, nó kiểm tra xem chúng ta có một số nguyên và một số dương tại đó hay không. Nếu không thì không có ích lợi gì. Nó cho phép 0 trượt qua là True (cần thiết hoặc khối tiếp theo là vòng lặp vô hạn).
Khối mã tiếp theo loại bỏ lũy thừa của 4 một cách có hệ thống trong một thuật toán con rất nhanh bằng cách sử dụng các phép toán dịch chuyển bit và logic bit. Cuối cùng, chúng ta không tìm thấy isSquare của n ban đầu của chúng ta mà là k <n đã được thu nhỏ theo lũy thừa 4, nếu có thể. Điều này làm giảm kích thước của số chúng tôi đang làm việc và thực sự tăng tốc phương pháp Babylon, nhưng cũng làm cho các kiểm tra khác cũng nhanh hơn.
Khối mã thứ ba thực hiện kiểm tra logic bit Boolean đơn giản. Ba chữ số có nghĩa nhỏ nhất, trong hệ nhị phân, của bất kỳ hình vuông hoàn hảo nào là 001. Luôn luôn. Dù sao, hãy để dành cho các số 0 đứng đầu từ lũy thừa của 4, đã được tính. Nếu nó không thành công trong bài kiểm tra, bạn ngay lập tức biết nó không phải là hình vuông. Nếu nó vượt qua, bạn không thể chắc chắn.
Ngoài ra, nếu chúng ta kết thúc bằng 1 cho giá trị thử nghiệm thì số thử nghiệm ban đầu là lũy thừa của 4, bao gồm cả chính nó có lẽ là 1.
Giống như khối thứ ba, khối thứ tư kiểm tra giá trị một vị trí trong số thập phân bằng cách sử dụng toán tử mô đun đơn giản và có xu hướng bắt các giá trị trượt qua lần kiểm tra trước. Cũng là một thử nghiệm mod 7, mod 8, mod 9 và mod 13.
Khối mã thứ năm kiểm tra một số mẫu hình vuông hoàn hảo nổi tiếng. Các số kết thúc bằng 1 hoặc 9 được đặt trước bội số của bốn. Và các số kết thúc bằng 5 phải kết thúc bằng 5625, 0625, 225 hoặc 025. Tôi đã đưa vào các số khác nhưng nhận ra rằng chúng thừa hoặc không bao giờ thực sự được sử dụng.
Cuối cùng, khối mã thứ sáu rất giống với câu trả lời của người trả lời hàng đầu - Alex Martelli -. Về cơ bản tìm căn bậc hai bằng cách sử dụng thuật toán Babylon cổ đại, nhưng giới hạn nó ở các giá trị nguyên trong khi bỏ qua dấu phẩy động. Thực hiện cho cả tốc độ và mở rộng độ lớn của các giá trị có thể kiểm tra được. Tôi đã sử dụng tập hợp thay vì danh sách vì nó mất ít thời gian hơn nhiều, tôi đã sử dụng dịch chuyển bit thay vì chia cho hai và tôi đã chọn một giá trị bắt đầu ban đầu một cách thông minh hiệu quả hơn nhiều.
Nhân tiện, tôi đã kiểm tra số thử nghiệm được đề xuất của Alex Martelli, cũng như một số con số mà nhiều đơn đặt hàng lớn hơn, chẳng hạn như:
x=1000199838770766116385386300483414671297203029840113913153824086810909168246772838680374612768821282446322068401699727842499994541063844393713189701844134801239504543830737724442006577672181059194558045164589783791764790043104263404683317158624270845302200548606715007310112016456397357027095564872551184907513312382763025454118825703090010401842892088063527451562032322039937924274426211671442740679624285180817682659081248396873230975882215128049713559849427311798959652681930663843994067353808298002406164092996533923220683447265882968239141724624870704231013642255563984374257471112743917655991279898690480703935007493906644744151022265929975993911186879561257100479593516979735117799410600147341193819147290056586421994333004992422258618475766549646258761885662783430625 ** 2
for i in range(x, x+2):
print(i, isSquare(i))
in các kết quả sau:
1000399717477066534083185452789672211951514938424998708930175541558932213310056978758103599452364409903384901149641614494249195605016959576235097480592396214296565598519295693079257885246632306201885850365687426564365813280963724310434494316592041592681626416195491751015907716210235352495422858432792668507052756279908951163972960239286719854867504108121432187033786444937064356645218196398775923710931242852937602515835035177768967470757847368349565128635934683294155947532322786360581473152034468071184081729335560769488880138928479829695277968766082973795720937033019047838250608170693879209655321034310764422462828792636246742456408134706264621790736361118589122797268261542115823201538743148116654378511916000714911467547209475246784887830649309238110794938892491396597873160778553131774466638923135932135417900066903068192088883207721545109720968467560224268563643820599665232314256575428214983451466488658896488012211237139254674708538347237589290497713613898546363590044902791724541048198769085430459186735166233549186115282574626012296888817453914112423361525305960060329430234696000121420787598967383958525670258016851764034555105019265380321048686563527396844220047826436035333266263375049097675787975100014823583097518824871586828195368306649956481108708929669583308777347960115138098217676704862934389659753628861667169905594181756523762369645897154232744410732552956489694024357481100742138381514396851789639339362228442689184910464071202445106084939268067445115601375050153663645294106475257440167535462278022649865332161044187890625 True
1000399717477066534083185452789672211951514938424998708930175541558932213310056978758103599452364409903384901149641614494249195605016959576235097480592396214296565598519295693079257885246632306201885850365687426564365813280963724310434494316592041592681626416195491751015907716210235352495422858432792668507052756279908951163972960239286719854867504108121432187033786444937064356645218196398775923710931242852937602515835035177768967470757847368349565128635934683294155947532322786360581473152034468071184081729335560769488880138928479829695277968766082973795720937033019047838250608170693879209655321034310764422462828792636246742456408134706264621790736361118589122797268261542115823201538743148116654378511916000714911467547209475246784887830649309238110794938892491396597873160778553131774466638923135932135417900066903068192088883207721545109720968467560224268563643820599665232314256575428214983451466488658896488012211237139254674708538347237589290497713613898546363590044902791724541048198769085430459186735166233549186115282574626012296888817453914112423361525305960060329430234696000121420787598967383958525670258016851764034555105019265380321048686563527396844220047826436035333266263375049097675787975100014823583097518824871586828195368306649956481108708929669583308777347960115138098217676704862934389659753628861667169905594181756523762369645897154232744410732552956489694024357481100742138381514396851789639339362228442689184910464071202445106084939268067445115601375050153663645294106475257440167535462278022649865332161044187890626 False
Và nó đã làm được điều này trong 0,33 giây.
Theo ý kiến của tôi, thuật toán của tôi hoạt động giống như của Alex Martelli, với tất cả các lợi ích của nó, nhưng có thêm lợi ích là từ chối kiểm tra đơn giản hiệu quả cao giúp tiết kiệm rất nhiều thời gian, chưa kể đến việc giảm kích thước của số thử nghiệm theo lũy thừa của 4, cải thiện tốc độ, hiệu quả, độ chính xác và kích thước của các con số có thể kiểm tra được. Có lẽ đặc biệt đúng trong các triển khai không phải Python.
Gần như 99% tất cả các số nguyên bị từ chối là không phải là Hình vuông trước khi thực hiện chiết tách từ gốc Babylon và trong 2/3 thời gian, người Babylon sẽ từ chối số nguyên. Và mặc dù những bài kiểm tra này không tăng tốc quá trình đáng kể, nhưng việc giảm tất cả các số kiểm tra đến số lẻ bằng cách chia tất cả lũy thừa của 4 thực sự đẩy nhanh bài kiểm tra Babylon.
Tôi đã làm một bài kiểm tra so sánh thời gian. Tôi đã thử nghiệm liên tiếp tất cả các số nguyên từ 1 đến 10 Triệu. Chỉ sử dụng phương pháp Babylon (với dự đoán ban đầu được điều chỉnh đặc biệt của tôi), Surface 3 của tôi đã mất trung bình 165 giây (với độ chính xác 100%). Chỉ sử dụng các bài kiểm tra logic trong thuật toán của tôi (không bao gồm Babylon), mất 127 giây, nó từ chối 99% tất cả các số nguyên là không phải là Hình vuông mà không từ chối nhầm bất kỳ hình vuông hoàn hảo nào. Trong số những số nguyên đã qua, chỉ 3% là Hình vuông hoàn hảo (mật độ cao hơn nhiều). Sử dụng thuật toán đầy đủ ở trên sử dụng cả các bài kiểm tra logic và phép chiết xuất từ gốc Babylon, chúng tôi có độ chính xác 100% và hoàn thành bài kiểm tra chỉ trong 14 giây. 100 Triệu số nguyên đầu tiên mất khoảng 2 phút 45 giây để kiểm tra.
CHỈNH SỬA: Tôi đã có thể rút ngắn thời gian hơn nữa. Bây giờ tôi có thể kiểm tra các số nguyên từ 0 đến 100 Triệu trong 1 phút 40 giây. Rất nhiều thời gian bị lãng phí để kiểm tra kiểu dữ liệu và tính tích cực. Loại bỏ hai lần kiểm tra đầu tiên và tôi cắt thử nghiệm xuống một phút. Người ta phải cho rằng người dùng đủ thông minh để biết rằng âm bản và dấu nổi không phải là hình vuông hoàn hảo.
import math
def is_square(n):
sqrt = math.sqrt(n)
return (sqrt - int(sqrt)) == 0
Hình vuông hoàn hảo là một số có thể được biểu thị dưới dạng tích của hai số nguyên bằng nhau. math.sqrt(number)
trả lại a float
. int(math.sqrt(number))
đưa kết quả đếnint
.
Nếu căn bậc hai là một số nguyên, chẳng hạn như 3, thì math.sqrt(number) - int(math.sqrt(number))
sẽ là 0 và if
câu lệnh sẽ là False
. Nếu căn bậc hai là một số thực như 3.2, thì nó sẽ là True
và in ra "nó không phải là một hình vuông hoàn hảo".
Nó không thành công đối với một không phải hình vuông lớn như 152415789666209426002111556165263283035677490.
if (math.sqrt(number)-int(math.sqrt(number))):
để a=math.sqrt(number)
sau đó một dòng khác cho: if a-int(a):
. Đây là vì nó chỉ có để tính căn bậc hai lần, mà imo cho n lớn có ý nghĩa
Câu trả lời của tôi là:
def is_square(x):
return x**.5 % 1 == 0
Về cơ bản, nó thực hiện một căn bậc hai, sau đó modulo bằng 1 để loại bỏ phần nguyên và nếu kết quả là 0 True
thì trả về ngược lại False
. Trong trường hợp này x có thể là bất kỳ số lớn nào, chỉ không lớn bằng số thực tối đa mà python có thể xử lý: 1.7976931348623157e + 308
Nó không chính xác cho một không phải hình vuông lớn như 152415789666209426002111556165263283035677490.
Điều này có thể được giải quyết bằng các decimal
mô-đun để lấy rễ chính xác vuông tùy ý và kiểm tra dễ dàng cho "tính chính xác":
import math
from decimal import localcontext, Context, Inexact
def is_perfect_square(x):
# If you want to allow negative squares, then set x = abs(x) instead
if x < 0:
return False
# Create localized, default context so flags and traps unset
with localcontext(Context()) as ctx:
# Set a precision sufficient to represent x exactly; `x or 1` avoids
# math domain error for log10 when x is 0
ctx.prec = math.ceil(math.log10(x or 1)) + 1 # Wrap ceil call in int() on Py2
# Compute integer square root; don't even store result, just setting flags
ctx.sqrt(x).to_integral_exact()
# If previous line couldn't represent square root as exact int, sets Inexact flag
return not ctx.flags[Inexact]
Để trình diễn với những giá trị thực sự to lớn:
# I just kept mashing the numpad for awhile :-)
>>> base = 100009991439393999999393939398348438492389402490289028439083249803434098349083490340934903498034098390834980349083490384903843908309390282930823940230932490340983098349032098324908324098339779438974879480379380439748093874970843479280329708324970832497804329783429874329873429870234987234978034297804329782349783249873249870234987034298703249780349783497832497823497823497803429780324
>>> sqr = base ** 2
>>> sqr ** 0.5 # Too large to use floating point math
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float
>>> is_perfect_power(sqr)
True
>>> is_perfect_power(sqr-1)
False
>>> is_perfect_power(sqr+1)
False
Nếu bạn tăng kích thước của giá trị đang được kiểm tra, điều này cuối cùng sẽ khá chậm (mất gần một giây cho hình vuông 200.000 bit), nhưng đối với những con số vừa phải hơn (ví dụ, 20.000 bit), nó vẫn nhanh hơn con người sẽ nhận thấy các giá trị riêng lẻ (~ 33 ms trên máy của tôi). Nhưng vì tốc độ không phải là mối quan tâm chính của bạn, nên đây là một cách tốt để làm điều đó với các thư viện chuẩn của Python.
Tất nhiên, sẽ nhanh hơn nhiều khi sử dụng gmpy2
và chỉ cần kiểm tra gmpy2.mpz(x).is_square()
, nhưng nếu các gói của bên thứ ba không phải là thứ của bạn, thì các cách trên hoạt động khá tốt.
Tôi chỉ đăng một biến thể nhỏ đối với một số ví dụ ở trên trên một chủ đề khác ( Tìm các hình vuông hoàn hảo ) và nghĩ rằng tôi sẽ bao gồm một biến thể nhỏ của những gì tôi đã đăng ở đây (sử dụng nsqrt làm biến tạm thời), trong trường hợp nó quan tâm / sử dụng:
import math
def is_square(n):
if not (isinstance(n, int) and (n >= 0)):
return False
else:
nsqrt = math.sqrt(n)
return nsqrt == math.trunc(nsqrt)
Nó không chính xác cho một không phải hình vuông lớn như 152415789666209426002111556165263283035677490.
Đây là phương pháp của tôi:
def is_square(n) -> bool:
return int(n**0.5)**2 == int(n)
Lấy căn bậc hai của số. Chuyển đổi thành số nguyên. Đi theo hình vuông. Nếu các số bằng nhau thì nó là một hình vuông hoàn hảo, ngược lại thì không.
Nó không chính xác cho một hình vuông lớn chẳng hạn như 152415789666209426002111556165263283035677489.
Bạn có thể tìm kiếm nhị phân cho căn bậc hai làm tròn. Bình phương kết quả để xem nó có khớp với giá trị ban đầu hay không.
Có lẽ bạn sẽ tốt hơn với câu trả lời của FogleBirds - mặc dù hãy cẩn thận, vì số học dấu phẩy động là gần đúng, có thể loại bỏ phương pháp này. Về nguyên tắc, bạn có thể nhận được một số dương sai từ một số nguyên lớn hơn một hình vuông hoàn hảo, chẳng hạn, do mất độ chính xác.
Câu trả lời này không liên quan đến câu hỏi đã nêu của bạn, nhưng đối với một câu hỏi ngầm mà tôi thấy trong mã bạn đã đăng, tức là "làm thế nào để kiểm tra xem một cái gì đó có phải là số nguyên hay không?"
Câu trả lời đầu tiên mà bạn thường nhận được cho câu hỏi đó là "Đừng!" Và đúng là trong Python, việc đánh máy thường không phải là điều đúng đắn.
Tuy nhiên, đối với những trường hợp ngoại lệ hiếm hoi đó, thay vì tìm kiếm dấu thập phân trong biểu diễn chuỗi của số, điều cần làm là sử dụng hàm isinstance :
>>> isinstance(5,int)
True
>>> isinstance(5.0,int)
False
Tất nhiên điều này áp dụng cho biến hơn là một giá trị. Nếu tôi muốn xác định xem giá trị có phải là số nguyên hay không, tôi sẽ làm như sau:
>>> x=5.0
>>> round(x) == x
True
Nhưng như những người khác đã trình bày chi tiết, có những vấn đề dấu phẩy động cần được xem xét trong hầu hết các ví dụ không phải đồ chơi về loại vật này.
Nếu bạn muốn lặp qua một phạm vi và thực hiện điều gì đó với mọi số KHÔNG phải là một hình vuông hoàn hảo, bạn có thể làm như sau:
def non_squares(upper):
next_square = 0
diff = 1
for i in range(0, upper):
if i == next_square:
next_square += diff
diff += 2
continue
yield i
Nếu bạn muốn làm điều gì đó cho mỗi số LÀ một hình vuông hoàn hảo, trình tạo thậm chí còn dễ dàng hơn:
(n * n for n in range(upper))
Tôi nghĩ rằng điều này hoạt động và rất đơn giản:
import math
def is_square(num):
sqrt = math.sqrt(num)
return sqrt == int(sqrt)
Nó không chính xác cho một không phải hình vuông lớn như 152415789666209426002111556165263283035677490.
set
Khi nào x in seen
là True
:
x
chuỗi của 511, 256, 129, 68, 41, 32, 31 , 31 ;Do đó, nó đủ để dừng ngay khi dòng điện x
lớn hơn hoặc bằng dòng điện trước đó:
def is_square(n):
assert n > 1
previous = n
x = n // 2
while x * x != n:
x = (x + (n // x)) // 2
if x >= previous:
return False
previous = x
return True
x = 12345678987654321234567 ** 2
assert not is_square(x-1)
assert is_square(x)
assert not is_square(x+1)
Tương đương với thuật toán ban đầu được thử nghiệm cho 1 <n <10 ** 7. Trong cùng một khoảng thời gian, biến thể đơn giản hơn một chút này nhanh hơn khoảng 1,4 lần.
a=int(input('enter any number'))
flag=0
for i in range(1,a):
if a==i*i:
print(a,'is perfect square number')
flag=1
break
if flag==1:
pass
else:
print(a,'is not perfect square number')
Ý tưởng là chạy một vòng lặp từ i = 1 đến tầng (sqrt (n)) sau đó kiểm tra xem bình phương nó có tạo ra n hay không.
bool isPerfectSquare(int n)
{
for (int i = 1; i * i <= n; i++) {
// If (i * i = n)
if ((n % i == 0) && (n / i == i)) {
return true;
}
}
return false;
}
import math
def is_square(n):
sqrt = math.sqrt(n)
return sqrt == int(sqrt)
Nó không thành công đối với một không phải hình vuông lớn như 152415789666209426002111556165263283035677490.