【发布时间】:2016-08-08 17:37:03
【问题描述】:
我目前有一个解决方案,但我觉得它没有解决这个问题的效率,所以我想看看是否有更快的方法来解决这个问题。
我有两个数组(例如 std::vectors)。两个数组都只包含唯一的整数值,这些值已排序但值稀疏,即:1,4,12,13 ...我想问的是有没有快速的方法可以找到其中一个数组的索引值是相同的。例如,array1 的值为 1,4,12,13,array2 的值为 2,12,14,16。 array2 中的第一个匹配值索引是 1。数组中的索引很重要,因为我有其他数组包含将使用此“匹配”索引的数据。
我并不局限于使用数组,地图也是可以的。我只比较这两个数组一次。在第一次匹配通过后,它们将不再被重复使用。任何一个数组中都可以有小到大数量的值(300,000+),但并不总是有相同数量的值(这会使事情变得更容易)
更糟糕的情况是线性搜索 O(N^2)。使用 map 会使我的 O(log N) 变得更好,但我仍然需要将数组转换为值、索引对的映射。
我目前不需要做任何容器类型转换的是这个。循环两个数组中较小的一个。将小数组 (array1) 的当前元素与大数组 (array2) 的当前元素进行比较。如果 array1 元素值大于 array2 元素值,则增加 array2 的索引,直到它不再大于 array1 元素值(while 循环)。然后,如果 array1 元素值小于 array2 元素,则进入下一个循环迭代并重新开始。否则它们必须相等,并且我对匹配值的任意一个数组都有我的索引。
所以在这个循环中,如果所有值都匹配,我充其量是 O(N),如果没有匹配,我最好是 O(2N)。所以我想知道那里是否有更快的东西?很难确定这两个数组匹配的频率,但我会更倾向于大多数数组将大部分匹配而不是不匹配。
我希望我已经充分解释了这个问题,并且感谢任何关于改进此问题的反馈或提示。
代码示例:
std::vector<int> array1 = {4,6,12,34};
std::vector<int> array2 = {1,3,6,34,40};
for(unsigned int i=0, z=0; i < array1.size(); i++)
{
int value1 = array1[i];
while(value1 > array2[z] && z < array2.size())
z++;
if (z >= array2.size())
break; // reached end of array2
if (value1 < array2[z])
continue;
// we have a match, i and z indices have same value
}
结果将匹配 array1 = [1,3] 和 array2= [2,3] 的索引
【问题讨论】:
-
添加了当前解决方案的示例代码
-
我很好奇,你需要这个算法的上下文是什么?
-
我正在使用它与两组数据之间的某种关联。简而言之,我有一些包含对象 ID 的数组。然后,我需要从另一个数组中的一组 ID 中收集数据,该数组可能在也可能不在前者中。通过查找数组中存在匹配项的索引,我可以使用该索引来提取基于该索引的各种其他数据。
-
O() 的定义中有一个隐含的常数因子,因此对于任何实数 C,0(x) 等价于 O(C*x)。基本上像 2 这样的常数因子被忽略在 O 表示法中。我实际上并没有建议像那样进行显式边界检查,而是在其中一个数组保持较小元素时查看 head-2、-4、-8 等的自适应算法。在这种情况下,当数组在我的示例中大部分不相交时,您只需要 ~lg(N) 检查。
标签: c++ arrays algorithm loops matching