最近遇到了一个需要矩阵去重的问题,我查阅了网上大部分的资料,发现都是说矩阵内部元素去重的问题,并没有说明相同矩阵如何去重。
先说下我的基本思路,去重很容易想到的就是用字典dict(python),map(Java,C++)也行。那么一个矩阵要变成一个数,对了就是hash。二维矩阵的hash需要同时考虑到行与列,分别都要进行hash。
考虑一维字符串hash的话,str = abcd,设P = 7。
这边abcd可以转成ASCII码来,当然若字符串较长指数爆炸的话可以取个模。
现在来考虑二维,原矩阵为A[n][m],很容易理解。假设有一个3 * 3的矩阵,h[i][j]表示矩阵A[i][j]的hash值,h[n][m]也就是矩阵A的hash值。行哈希与原一维字符串哈希一样就行,列哈希我们选择把行hash再进行hash。下面看代码:
for p in range(squ1):
for i in range(0, n):
for j in range(0, m):#行hash
if j - 1 >= 0:
h[p][i][j] = (h[p][i][j - 1] * seed1 + result2[p][i][j] + 1)
if j - 1 < 0:
h[p][i][j] = (0 * seed1 + result2[p][i][j])#对于第一个,设为原矩阵的值就行
h[p][i][j]这里是指第p个矩阵中i行j列这个矩阵的hash值
for p in range(squ1):
for i in range(0, n):
for j in range(0, m):#列hash
if i - 1 >= 0:
h[p][i][j] = (h[p][i - 1][j] * seed2 + h[p][i][j])
else:
h[p][i][j] += h[p][i][j]
注意行列的seed不要选择一样的质数,这里选择seed1 = 131,seed2 = 13331
现在h[p][n][m],表示第p个矩阵的hash值。
算出来后用dict去重就行了,待去重的矩阵也用上述算法算一次就好了,本文没有考虑最大支持多少矩阵会产生hash冲突,但是本人20w个矩阵的去重是没有发生冲突的。
mp = dict()
flag = 0
for p in range(squ1):
mp.setdefault(h[p][n - 1][n - 1], 1)
for p in range(squ2):
if mp.get(h2[p][n - 1][n - 1]) != 1:
with open("C:\\Users\\52221\\Desktop" + '\\unique1.txt','a') as file:
file.write("Graph " + str(flag) + ",order 9.\n")
flag += 1
for i in range(n):
for j in range(n):
file.write(str(result1[p][i][j]) + " ")
file.write("\n")
file.write("\n")