C++中set用法详解

mac2026-03-17  2

C++中set用法详解

参考链接

C++中set用法详解

set原因

当数据元素增多时,set的插入和搜索速度变化如何?

如果你知道log2的关系你应该就彻底了解这个答案。在set中查找是使用二分查找,也就是说,如果有16个元素,最多需要比较4次就能找到结果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素呢?最多不过15次。看见了吧,当数据量增大一倍的时候,搜索次数只不过多了1次,多了1/14的搜索时间而已。你明白这个道理后,就可以安心往里面放入元素了。

工程范例(较乱,笔记)

set<MapPoint*> sFound; //遍历所有内点 for(int j=0; j<np; j++) { if(vbInliers[j]) { mCurrentFrame.mvpMapPoints[j]=vvpMapPointMatches[i][j]; sFound.insert(vvpMapPointMatches[i][j]); } else mCurrentFrame.mvpMapPoints[j]=NULL; } int nadditional =matcher2.SearchByProjection( mCurrentFrame, //当前帧 vpCandidateKFs[i], //关键帧 sFound, //已经找到的地图点集合 10, //窗口阈值 100); //ORB描述子距离 int ORBmatcher::SearchByProjection(Frame &CurrentFrame, KeyFrame *pKF, const set<MapPoint*> &sAlreadyFound, const float th , const int ORBdist) { int nmatches = 0; const cv::Mat Rcw = CurrentFrame.mTcw.rowRange(0,3).colRange(0,3); const cv::Mat tcw = CurrentFrame.mTcw.rowRange(0,3).col(3); const cv::Mat Ow = -Rcw.t()*tcw; // Rotation Histogram (to check rotation consistency) vector<int> rotHist[HISTO_LENGTH]; for(int i=0;i<HISTO_LENGTH;i++) rotHist[i].reserve(500); const float factor = HISTO_LENGTH/360.0f; const vector<MapPoint*> vpMPs = pKF->GetMapPointMatches(); // 遍历关键帧中的每个地图点 for(size_t i=0, iend=vpMPs.size(); i<iend; i++) { MapPoint* pMP = vpMPs[i]; if(pMP) { if(!pMP->isBad() && !sAlreadyFound.count(pMP)) { //Project cv::Mat x3Dw = pMP->GetWorldPos(); cv::Mat x3Dc = Rcw*x3Dw+tcw; const float xc = x3Dc.at<float>(0); const float yc = x3Dc.at<float>(1); const float invzc = 1.0/x3Dc.at<float>(2); const float u = CurrentFrame.fx*xc*invzc+CurrentFrame.cx; const float v = CurrentFrame.fy*yc*invzc+CurrentFrame.cy; if(u<CurrentFrame.mnMinX || u>CurrentFrame.mnMaxX) continue; if(v<CurrentFrame.mnMinY || v>CurrentFrame.mnMaxY) continue; // Compute predicted scale level cv::Mat PO = x3Dw-Ow; float dist3D = cv::norm(PO); const float maxDistance = pMP->GetMaxDistanceInvariance(); const float minDistance = pMP->GetMinDistanceInvariance(); // Depth must be inside the scale pyramid of the image if(dist3D<minDistance || dist3D>maxDistance) continue; int nPredictedLevel = pMP->PredictScale(dist3D,&CurrentFrame); const float radius = th*CurrentFrame.mvScaleFactors[nPredictedLevel]; const vector<size_t> vIndices2 = CurrentFrame.GetFeaturesInArea(u, v, radius, nPredictedLevel-1, nPredictedLevel+1); if(vIndices2.empty()) continue; const cv::Mat dMP = pMP->GetDescriptor(); int bestDist = 256; int bestIdx2 = -1; for(vector<size_t>::const_iterator vit=vIndices2.begin(); vit!=vIndices2.end(); vit++) { const size_t i2 = *vit; if(CurrentFrame.mvpMapPoints[i2]) continue; const cv::Mat &d = CurrentFrame.mDescriptors.row(i2); const int dist = DescriptorDistance(dMP,d); if(dist<bestDist) { bestDist=dist; bestIdx2=i2; } } if(bestDist<=ORBdist) { CurrentFrame.mvpMapPoints[bestIdx2]=pMP; nmatches++; if(mbCheckOrientation) { float rot = pKF->mvKeysUn[i].angle-CurrentFrame.mvKeysUn[bestIdx2].angle; if(rot<0.0) rot+=360.0f; int bin = round(rot*factor); if(bin==HISTO_LENGTH) bin=0; assert(bin>=0 && bin<HISTO_LENGTH); rotHist[bin].push_back(bestIdx2); } } } } } if(mbCheckOrientation) { int ind1=-1; int ind2=-1; int ind3=-1; ComputeThreeMaxima(rotHist,HISTO_LENGTH,ind1,ind2,ind3); for(int i=0; i<HISTO_LENGTH; i++) { if(i!=ind1 && i!=ind2 && i!=ind3) { for(size_t j=0, jend=rotHist[i].size(); j<jend; j++) { CurrentFrame.mvpMapPoints[rotHist[i][j]]=NULL; nmatches--; } } } } return nmatches; }
最新回复(0)