C++ 在二维向量中搜索数字序列的更快方法是什么?

C++ 在二维向量中搜索数字序列的更快方法是什么?,c++,algorithm,c++11,search,vector,C++,Algorithm,C++11,Search,Vector,给定一个具有整数值的2d数组(数组可以大于10k*10k),在数组中搜索给定数字序列的更快方法是什么 假设文件中的2d数组被读入一个大的1d向量,并作为大矩阵(行*x+宽度)访问。 我希望在同一个2d数组上执行3种类型的搜索。它们是搜索有序、搜索无序、搜索最佳匹配。下面是我对每个搜索函数的处理方法 按顺序搜索:此函数查找存在给定数字序列(数字顺序)的所有行。以下是我实现的用于查找给定数字序列的KMP方法: void searchPattern(std::vector<int> con

给定一个具有整数值的2d数组(数组可以大于10k*10k),在数组中搜索给定数字序列的更快方法是什么

假设文件中的2d数组被读入一个大的1d向量,并作为大矩阵(行*x+宽度)访问。 我希望在同一个2d数组上执行3种类型的搜索。它们是搜索有序、搜索无序、搜索最佳匹配。下面是我对每个搜索函数的处理方法

按顺序搜索:此函数查找存在给定数字序列(数字顺序)的所有行。以下是我实现的用于查找给定数字序列的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++;
        }
    }
}
void searchPattern(std::vector const&pattern,std::vector const&big_矩阵,int begin,int finish,
整数宽度,标准::向量和搜索结果){
autom=(int)pattern.size();
自动N=宽度;//一行的大小
while(开始<结束){
int i=0;
int j=0;
而(i
复杂度: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 */
    }
}
void SearchUnordered/BestMatch(std::vector const&match,std::vector const&big_matrix_排序,int begin,int finish,
整数宽度,标准::向量和搜索结果){
std::vector::it迭代器;
std::vector v(match.size()+宽度);
while(开始<结束){
it=std::set_交叉点(match.begin()、match.end()、big_矩阵_sorted.begin()+begin*宽度,
大矩阵排序。开始()+开始*宽度+宽度,v.开始());
v、 调整大小(it-v.begin());
如果(v.size()==subseq.size())
搜索结果[开始]=开始;
其他的
搜索结果[开始]=-1;
begin++;
/*对于搜索最佳匹配,最后几行将更改如下:
searchResult[begin]=(int)v.size();
begin++;搜索结果中最大的是结果*/
}
}
复杂性:O(m*(l+n));l-图案的长度,m是行数,n是列数


大矩阵的预处理(构造查找表,存储排序后的版本。您可以做任何预处理工作。)不考虑。如何提高这些搜索函数的复杂度(到O(log(m*n))?

如果您希望整体速度更快,但已经有了正确的算法。您可以通过优化代码(内存分配,如果编译器没有,删除重复操作等)来获得一些性能。例如,通过删除两个
大矩阵[(行*宽)+i]
并将其分配给局部变量,可能会有增益。请小心分析和测量实际情况

对于较大的增益,线程可以是一个选项。您可以一次处理一行,因此应该大致与内核数的线性加速。C++ 11有“代码> STD::Assic < /Cuff>,它可以处理一些启动线程并获得结果的工作,而不是处理<代码> STD::Tox<代码>您自己或平台特定的机制。还有一些其他更新的东西,在新版本的C++中也很有用。

void searchPatternRow(std::vector<int> const &pattern, std::vector<int> const &big_matrix, int row, int width, std::vector<int> &searchResult);
void searchPattern(std::vector<int> const &pattern, std::vector<int> const &big_matrix, int begin, int finish, int width, std::vector<int> &searchResult)
{
    std::vector<std::future<void>> futures;
    for (int row = begin; row < finish; ++row)
        std::async([&, row]() { searchPatternRow(pattern, big_matrix, row, width, searchResult);  });
    for (auto &future : futures) future.wait(); // Note, also implicit when the future from async gets destructed
}
void searchPatternRow(std::vector const&pattern,std::vector const&big_矩阵,int row,int width,std::vector&searchResult);
void searchPattern(std::vector const&pattern,std::vector const&big_矩阵,int begin,int finish,int width,std::vector&searchResult)
{
向量期货;
对于(int行=开始;行<完成;++行)
std::async([&,row](){searchPatternRow(pattern,big_矩阵,row,width,searchResult);});
for(auto&future:futures)future.wait();//注意,当来自异步的未来被破坏时也是隐式的
}

为了提高线程效率,您可能需要批处理和搜索,比如10行。对于
searchResult

线程写入同一缓存线也有一些注意事项,在搜索精确匹配时,您可以通过使用我称之为“移动哈希”的方法来非常有效地完成此操作

搜索时,计算搜索字符串上的哈希值,同时计算正在搜索的数据上的移动哈希值。进行比较时,首先比较哈希值,只有在匹配时,才继续比较实际数据

现在,勾号是选择一个哈希算法,该算法可以在每次移动一个点时轻松更新,而不是重新计算所有内容。例如,所有数字的总和

如果我有以下数组:
012345678901234567890
并且我想在此数组中查找
34567
,我可以将哈希定义为搜索字符串中所有数字的总和。这将给出一个哈希值
25
(3+4+5+6+7)。然后,我将搜索整个数组,并不断更新数组上正在运行的哈希值。数组中的第一个哈希值将是
10
(0+1+2+3+4)和se