【发布时间】:2019-03-13 00:10:51
【问题描述】:
给定一个具有整数值的二维数组(数组可以大于 10k*10k),在数组中搜索给定数字序列的更快方法是什么?
假设文件中的二维数组被读入一个大的一维向量,并以 big_matrix(row*x+width) 的形式访问。 我想在同一个二维数组上进行 3 种类型的搜索。它们是搜索有序、搜索无序、搜索最佳匹配。这是我对每个搜索功能的处理方法。
Search Ordered:此函数查找存在给定数字顺序(数字顺序很重要)的所有行。这是我实现的查找给定数字序列的 KMP 方法:
void searchPattern(std::vector<int> const &pattern, std::vector<int> const &big_matrix, int begin, int finish,
int width, std::vector<int> &searchResult) {
auto M = (int) pattern.size();
auto N = width; // size of one row
while (begin < finish) {
int i = 0;
int j = 0;
while (i < N) {
if (pattern[j] == big_matrix[(begin * width) + i]) {
j++;
i++;
}
if (j == M) {
searchResult[begin] = begin;
begin++;
break;
} else if (i < N && pattern[j] != big_matrix[(begin * width) + i]) {
if (j != 0)
j = lps[j - 1]; // lookup table as in KMP
else
i = i + 1;
}
}
if (j != M) {
searchResult[begin] = -1;
begin++;
}
}
}
复杂度:O(m*n); m是行数,n是列数
搜索无序/搜索最佳匹配:此函数查找存在给定数字序列的所有行(数字顺序无关紧要)。 在这里,我最初对大数组进行排序,并且在搜索期间仅对输入数组进行排序。
void SearchUnordered/BestMatch(std::vector<int> const &match, std::vector<int> const &big_matrix_sorted, int begin, int finish,
int width, std::vector<int> &searchResult) {
std::vector<int>::iterator it;
std::vector<int> v(match.size() + width);
while (begin < finish) {
it = std::set_intersection(match.begin(), match.end(), big_matrix_sorted.begin() + begin * width,
big_matrix_sorted.begin() + begin * width + width, v.begin());
v.resize(it - v.begin());
if (v.size() == subseq.size())
searchResult[begin] = begin;
else
searchResult[begin] = -1;
begin++;
/* For search best match the last few lines will change as follows:
searchResult[begin] = (int) v.size();
begin++; and largest in searchResult will be the result */
}
}
复杂度:O(m*(l + n)); l - 模式的长度,m是行数,n是列数。
big_matrix 的预处理(构建查找表,存储它的排序版本。您可以进行任何预处理。)不考虑 .如何提高这些搜索函数的复杂度(到 O(log (m*n))?
【问题讨论】:
-
"假设文件中的二维数组被读入一个大的一维向量并作为 big_matrix(rowx+width)"* - 如果我们可以假设那么我认为这只是一个
1d数组问题。 -
@Galik 你可以这样想,但你必须返回与搜索条件匹配的行索引。
-
我认为缓慢的部分将是搜索。从绝对偏移量中发现行和列的数学运算将在百万分之几秒内发生。你试过std::search吗?您可能会从使用 boyer_more_searcher 中受益。
-
@Galik 是的,我已经尝试过
std::search,但我没有发现性能发生了巨大变化。我的实现显然没有利用它们是数字的事实。我正在做类似于我们对字符串所做的事情。有没有办法减少搜索空间?我收到的一个提示是建立一个查找表,但我没有得到任何线索。 -
我认为您永远无法摆脱这样一个事实,即如果您添加新行,则必须搜索所有行,并且搜索将取决于列数。因此,您最终将始终将基于列的搜索时间乘以行数。 (对于无序搜索)
标签: c++ algorithm c++11 search vector