所以,我有一个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;
}
答案 0 :(得分:2)
我认为有三件事需要考虑:
int a[X][Y]
表时,我会创建其他数组int[6][Y]
,其中包含:
答案 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中工作时,它限制了可用的数据结构: 我建议:
取决于2D输入数组的类型:您可以使用边界条件节省一些时间,因为您希望查询数组的所有元素都保持顺序。您还可以使用(Z <= Y)每行的长度来匹配是否应该首先匹配长度。
对数组进行排序会增加其复杂性。最好避免它。