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

时间:2016-09-13 09:46:35

标签: 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++;
        }
    }

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

1 个答案:

答案 0 :(得分:2)

现在编写代码时,复杂度为Θ(n m),其中 n m 是序列的大小。至少有两种方法可以改善这种情况(第二种方法更有效,但编码更难)。

  • 在外环的主体中,不要通过while(found == false && jt!=depth_images.end())遍历第二个地图中的所有元素。相反,请使用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 是此范围的大小。

  • 由于地图的键已排序,您可以修改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;
     }