这是Matt's algorithm 的 Python 实现。
-
AB 创建和隐藏A 和B,只提供比较A[i] 和B[j] 并检查索引列表I 和J 是否完美匹配。
-
quickmatch是解算法
演示输出显示计算出的I、J 以及它们是否完美匹配:
[16, 0, 19, 7, 10, 15, 12, 14, 5, 4, 11, 18, 1, 9, 2, 6, 13, 8, 3, 17]
[1, 3, 13, 12, 0, 18, 9, 4, 14, 17, 11, 6, 5, 7, 15, 2, 8, 10, 16, 19]
True
代码:
from random import shuffle
class AB:
def __init__(self, n):
A = list(range(n))
B = list(range(n))
shuffle(A)
shuffle(B)
def cmp(i, j):
a = A[i]
b = B[j]
return -1 if a < b else 1 if a > b else 0
def check(I, J):
if not (sorted(I) == sorted(J) == list(range(n))):
return False
return all(A[i] == B[j] for i, j in zip(I, J))
self.cmp = cmp
self.check = check
def quickmatch(I, J):
if not I:
return I, J
ipivot = I[0]
jpivot = next(j for j in J if ab.cmp(ipivot, j) == 0)
small_I = [i for i in I if ab.cmp(i, jpivot) < 0]
small_J = [j for j in J if ab.cmp(ipivot, j) > 0]
small_I, small_J = quickmatch(small_I, small_J)
large_I = [i for i in I if ab.cmp(i, jpivot) > 0]
large_J = [j for j in J if ab.cmp(ipivot, j) < 0]
large_I, large_J = quickmatch(large_I, large_J)
return (small_I + [ipivot] + large_I,
small_J + [jpivot] + large_J)
# Create a test case
n = 20
ab = AB(n)
# Solve
I = list(range(n))
J = list(range(n))
I, J = quickmatch(I, J)
# Check
print(I)
print(J)
print(ab.check(I, J))