2D阵列中最快的搜索算法

时间:2017-10-31 18:51:58

标签: c algorithm search

所以,我有一个2D数组,int a[X][Y]; X最高可达 10 000 000 Y最高 6 。 给定数组int v[Z] Z< = Y ),我必须查看是否在包含v的所有元素的行中找到了一行。

这个问题的最快算法是什么?你会如何实现?

我已经尝试过逐行获取的经典方法,然后使用2个fors搜索,一个用于v元素,一个用于元素但是它需要太长时间。

什么是最好(最快)的方法?

int check()
{
    int nrfound;

    for (int l = 0; l < lines_counter; l++) for each line in a array
    {
        nrfound = 0;

        for (int i = 0; i < n; i++) { // for each element in v array

            for (int j = 0; j < m; j++) // for each element in a[l] line
                if (v[i] == a[l][j])
                    nrfound++;
            if (nrfound == Z)
                return 0;
        }
    }
    return 1;
}

5 个答案:

答案 0 :(得分:2)

我认为有三件事需要考虑:

  • 使用线程。
  • 如果可能,在构建int a[X][Y]表时,我会创建其他数组int[6][Y],其中包含:
    • 包含1,2,3 ... 6个元素的索引列表。这样可以缩小搜索范围。
  • 对于每个X计数哈希的值。然后计算V值的哈希值。
    • 比较哈希代码,而不是每个单独的值。

答案 1 :(得分:1)

对于重复使用相同数组的情况a []具有多个不同的v []:

将[] []的每一行排序为预备步骤(执行一次)

排序v []

使用单循环(而不是两个)来获得有序v []与[]的每个有序行的交集 - 使用类似merge合并排序过程的方法

index_v = 0
index_a = 0
while index_v < length_v and index_a < length_a:
   if v[index_v] == a[index_a]
       index_v++, index_a++
   else if v[index_v] < a[index_a]
       index_v++   
   else
     index_a++
if index_v == length_v:
   return OK, a[] line contains all v elements

答案 2 :(得分:0)

使用带或不带Simd /多线程的固定排序网络,可以轻松地对大小为6的1e7阵列进行排序。

排序v并将其与合并排序两个排序列表的原理进行比较。

总体最差情况复杂度在13e7..24e7之间进行比较(6个元素的排序网络需要12个条件互换,合并v / a [n]需要1..12个比较。

答案 3 :(得分:0)

如果a[i][]子阵列中存在重复元素,则您的算法存在缺陷。 v的匹配元素将被多次计算,并且计数可能等于Z巧合。

以下是更正后的版本:

int check(int X, int Y, int Z, int a[X][Y], int v[Z]) {
    for (int x = 0; x < X; x++) {
        // for each line in array a
        int mask = 0;
        for (int z = 0; z < Z; z++) {
            // for each element in array v
            for (int y = 0, m = 1; y < Y; y++, m <<= 1) {
                // for each element in line a[x]
                if (v[z] == a[x][y] && !(mask & m)) {
                    mask |= m;
                    break;
                }
            }
            if (y == Y)
                break;
        }
        if (z == Z)
            return 0;   // found a match
        }
    }
    return 1;   // no match
}

不幸的是,上面的代码可能比发布的代码更慢,但值得测试,因为只要在v中找不到a[x]的元素,就会退出内部循环。< / p>

答案 4 :(得分:0)

当您在C中工作时,它限制了可用的数据结构: 我建议:

  • 初始化N个线程,在N个桶中划分矩阵行X,并并行运行搜索每个桶。
  • 取决于2D输入数组的类型:您可以使用边界条件节省一些时间,因为您希望查询数组的所有元素都保持顺序。您还可以使用(Z <= Y)每行的长度来匹配是否应该首先匹配长度。

  • 对数组进行排序会增加其复杂性。最好避免它。