与其用 C++ 重写,不如先考虑改进算法。最低可能的答案是原始值的平方根,所有“?” 替换为四舍五入的 0,可能的最高答案是模式的平方根,将“?”替换为向下舍入的 1。找到这两个值,遍历它们,平方并检查模式。
这更快,因为您迭代的数字要少得多,而且因为您没有在循环中计算任何平方根:平方要容易得多。
您无需比较字符串即可检查匹配项:
mask = int(pattern.replace('0', '1').replace('?', '0'), 2)
test = int(pattern.replace('?', '0'), 2)
def is_match(n):
return (n&mask)==test
所以把它们放在一起:
def int_sqrt(x):
if x < 0:
raise ValueError('square root not defined for negative numbers')
n = int(x)
if n == 0:
return 0
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
def find_match(pattern):
lowest = int(pattern.replace('?', '0'), 2)
highest = int(pattern.replace('?', '1'), 2)
mask = int(pattern.replace('0', '1').replace('?', '0'), 2)
lowsqrt = int_sqrt(lowest)
if lowsqrt*lowsqrt != lowest:
lowsqrt += 1
highsqrt = int_sqrt(highest)
for n in range(lowsqrt, highsqrt+1):
if (n*n & mask)==lowest:
return n*n
print(find_match('1??1??1'))
print(find_match('1??0??1'))
print(find_match('1??????????????????????????????????????????????????????????????????????1??0??1'))
输出:
121
81
151115727461209345152081
注意 这仅适用于 Python 3.x,最后一个测试将range
在 Python 2.x 中溢出