lundi 8 octobre 2018

What is the faster way to search for sequence of numbers in a 2d vector?

Given a 2d array(the array can be larger than 10k*10k) with integer values, What is the faster way to search for given sequence of numbers in array?

Assume the 2d array which is in file is read into a big 1d vector and is accessed as big_matrix(row*x+width). There are 3 types of searches I would like to do on the same 2d array. They are Search Ordered, Search Unordered, Search Best Match. Here's my approach to each of the search functions.

Search Ordered: This function finds all the rows in which given number sequence(order of numbers matters) is present. Here's the KMP method to find the given number sequence I implemented:

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++;
        }
    }
}

Complexity: O(m*n); m is the number of rows, n is the number of cols

Search Unordered/Search Best Match: This function finds all the rows in which given number sequence is present(order of numbers doesn't matter). Here I am sorting the large array initially and will just sort only the input array during search.

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 */
    }
}

Complexity: O(m*(l + n)); l - length of the pattern, m is the number of rows, n is the number of cols.

Preprocessing of big_matrix(Constructing lookup table, storing a sorted version of it. You're allowed to do any pre-proccesing stuff.) is not taken into consideration. How can I improve the complexity(to O(log (m*n)) of these search functions?

Aucun commentaire:

Enregistrer un commentaire