我有一个NxN
(2 <= N <= 800)
更大的二维字符网格。我获得了KxK
( 2 <= K <= 100)
的较小的2d网格。例如,设N = 3且K = 2,以下是矩阵,
放大:
abc
abd
aaa
小:
bd
aa
问题1: 如果较大的矩阵包含较小的矩阵,我必须返回。例如,在较大的矩阵内部匹配较小的矩阵。
问题2 :如果找到,我必须返回NxN
上的凝视位置糖化部分。上面的示例返回匹配并且position = (1, 1)
#0基于
我的假设:
我的假设是使用哈希。但仍然有更好的想法有效搜索。例如,我可以创建一个哈希函数,它将为所有有效位置生成NxN(2x2,3x3,4x4,...,100x100,因为K可以达到100)的所有可能方格的索引
(0,0), (0,1), ..., (0, N-K)
(1,0), (1,1), ..., (1, N-K)
. .
. .
(N-K,0), (N-K, 1) .... (N-K, N-K)
然后我可以在关联的索引中保持位置,当输入KxK到来时,我只运行相同的哈希函数,看看返回的索引是否有位置。
答案 0 :(得分:1)
这个问题的技巧是使用一个哈希函数,当你移动一个位置时,你可以在O(1)中更新。这会将复杂性降低到O(N ^ 2)。
此类哈希函数的示例是h = sum(x[i] * 2^i) % some_large_prime_number
。其中x[i]
是第i个字符的ascii代码。要更新你会做
h_new = ((h_previous -
(x[position_to_remove] * 2^k)) * 2 +
(x[position_to_add] * 2^0
) % some_large_prime_number`
哈希函数不是很强,所以你会得到一些误报。 为了提高匹配的可信度,重复使用几个不同的大素数的算法。它仍然可能产生误报,但它们很少见。
注意:注意选择一个不会溢出整数类型的素数。您可以应用&#39;%&#39;对中间结果进行操作以及防止溢出。还有&#39;%&#39;对于负输入,模运算将在大多数语言中返回一个负数(当你进行减法时,你需要自己包围)。