C++ 在两个 std::map 之间查找匹配项的有效方法

标签 c++ algorithm dataset matching stdmap

我有一个用 RGB-D 相机采集的数据集和一个文本文件,其中存储了数据集的每个图像的时间戳和文件名。我所做的是解析这个文件并填充两个 std::map,一个用于 rgb 图像,另一个用于深度图像。现在,由于时间戳不相交,我必须编写一个例程来根据时间戳查找匹配的图像。这是我到目前为止写的:

typedef map<double,string> StampImageMap;

...

vector<string> &vstrImageFilenamesRGB;
vector<string> &vstrImageFilenamesD;
vector<double> &vTimestampsRGB;
vector<double> &vTimestampsDPT;

double tolerance = 0.02;

for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) {
        bool found = false;
        StampImageMap::iterator jt=depth_images.begin();
        while(found == false && jt!=depth_images.end()) {
            if(fabs(it->first - jt->first) < tolerance) {
                found = true;
                vstrImageFilenamesRGB.push_back(it->second);
                vstrImageFilenamesD.push_back(jt->second);
                vTimestampsRGB.push_back(it->first);
                vTimestampsDPT.push_back(jt->first);
            }
            jt++;
        }
    }

我想知道是否有更有效的方法来执行此任务!

最佳答案

按照您现在编写的代码,复杂度为 Θ(n·m),其中 nm 是序列的大小。至少有两种方法可以改进这一点(第二种更有效,但更难编码)。

  • 在外部循环体中,不要通过while(found == false && jt!=depth_images.end()) 遍历第二个 map 中的所有元素。相反,使用 std::map::lower_boundstd::map::upper_bound 分别搜索 it->first - toleranceit->first + tolerance。仅在这两个调用的结果之间循环。

    所以,代码变成了这样:

    for(StampImageMap::iterator it=rgb_images.begin(); it != rgb_images.end(); it++) {
        StampImageMap::const_iterator lower = depth_images.lower_bound(it->first - tolerance);
        StampImageMap::const_iterator upper = depth_images.lower_bound(it->first + tolerance);
    
        // Now just search between lower and upper.
    }
    

    这会将每次迭代减少到 Θ(log(m)) + p,其中 p 是该范围的大小。

  • 由于 map 的键是排序的,你可以修改一个standard technique of finding the intersection of two sorted arrays对于这种情况。这会将运行时间减少到Θ(m + n)。请注意,修改有点棘手,因为您不是要查找精确元素的交集,而是要查找“足够接近”元素的交集。

    这里是这个案例的伪代码:

     it = rgb_image.begin();
     jt = depth_image.begin();
    
     while(it != rgb_image.end() && jt != depth_image.end()) {
         if(fabs(it->first - jt->first) < tolerance) {
             // Match found!
             ++it;
             ++jt;
             continue;
         }
    
         if(it.first > jt.first + tolerance) {
             ++jt;
             continue;
         }
    
         ++it;
     }
    

关于C++ 在两个 std::map 之间查找匹配项的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39466943/

相关文章:

r - 为什么Ifelse无法取代NA?

C++ 如何声明指向二维数组的指针

c++ - 从 SFML 提供的 X11 句柄创建 Irrlicht 设备。运行时 X11/OpenGL 错误

C++ 访问级别

C++内存分配问题

c++ - 二进制文件中的模式搜索

c# - 将 DataRow[] 转换为 DataTable 而不会丢失其 DataSet

java - 如何从n组不同大小的数字中选择n个数字?

c# - 升序排列

c# - 获取 2 个数据集 c# 中的差异