【发布时间】:2015-06-03 05:34:31
【问题描述】:
我有一个由一对向量(V1,V2)组成的向量,称为pairV1V2,形式如下:
(1,2,3),(938,462,4837) -> (V1,V2)
(3,9,13),(938,0472,944)
(81,84,93),(938,84,845)
那我需要保留以下内容:
(1,2,3),(938,462,4837) -> (V1,V2)
(3,9,13),(938,0472,944)
(81,84,93),(84,845)
我需要从头开始扫描pairV1V2,如果任何两个V1 不相等,我需要从V2 中删除相交的元素。我写了下面的代码来做同样的事情。然而,我的代码效率非常低,因为我的向量对 V1V2 很大,而且它在 V2 中有很多元素(大约十亿)。
int main(int argc, char** argv) {
std::vector<std::pair<std::vector<unsigned>, std::vector<unsigned> > > pairV1V2;
std::vector<std::pair <std::vector<unsigned>,std::vector<unsigned> > >::iterator itm2,lm2=pairV1V2.end();
for(std::vector<std::pair <std::vector<unsigned>,std::vector<unsigned> > >::iterator itm=pairV1V2.begin(), lm=pairV1V2.end(); itm!=lm; ++itm)
{
//Outer values
vector<unsigned> outerV1=(*itm).first;
vector<unsigned> outerV2=(*itm).second;
sort(outerV2.begin(), outerV2.end());
itm2=itm;
itm2++;
for(itm2;itm2!=lm2;++itm2)
{
vector<unsigned> innerV1=(*itm2).first;
vector<unsigned> innerV2=(*itm2).second;
vector<unsigned> setDiffV1;
std::set_difference(innerV1.begin(), innerV1.end(), outerV1.begin(), outerV1.end(),
std::inserter(setDiffV1, setDiffV1.end()));
if(setDiffV1.size()==0) //check whether any two V1's are different
{
sort(innerV2.begin(), innerV2.end());
if((itm->second.size()!=0)&&(itm2->second.size()!=0)){
std::vector<unsigned> delIntersectingElem;
std::set_intersection(outerV2.begin(),outerV2.end(),innerV2.begin(), innerV2.end(),
std::back_inserter(delIntersectingElem));
if(delIntersectingElem.size()!=0) //if there are intersecting V2's
{
for(std::vector<unsigned>::iterator its=(itm2->second).begin(),ls=(itm2->second).end();its!=ls;)
{
//if *its is present in delIntersectingElem then delete it.
if(!(std::find(delIntersectingElem.begin(), delIntersectingElem.end(), (*its)) == delIntersectingElem.end()))
{
(itm2->second).erase(its); //delete intersecting elements from inner v2
ls--;
}else{
++its;
}
}
}
}
}
}
}
return 0;
}
有人可以帮我改进我现在的代码吗——它给出了正确的答案(在这个例子中,为了简洁起见,我可能遗漏了几个案例——但代码处理了所有这些)但是非常慢(因为对角化通过性能)。如果在我目前的代码中提出改进建议,我将不胜感激。但是,如果两个代码的逻辑相同,那么新的算法也是可以接受的
【问题讨论】:
-
如果您要进行大量擦除和顺序访问,您是否考虑过使用 std::list?
-
@user4581301 好的..我不知道 std::list,你能告诉我如何使用 std::list 改进我目前的代码
-
为了帮助改进代码,你真的应该访问codereview.stackexchange.com而不是堆栈溢出。
-
您似乎应该复制构建外部和内部向量。这么多内存分配/释放真的有必要吗?
-
使用列表在很大程度上取决于您在代码的其他部分中如何使用要从中删除的向量。如果您所做的只是添加到向量中,然后从中删除,那么列表带来的删除速度比向量所能提供的要快得多。如果您要进行筛选和排序,那么列表很糟糕。