我正在尝试比较2个不同的向量以捕获任何重复项。一个向量是10个数字中的500万个元素,另一个是10个元素中的280万个元素。 我的操作系统是ubuntu 18.04,我正在使用QtCreator。当我尝试比较这些大向量时,我遇到了麻烦。这是我尝试过的:
vector<vector<int> >::iterator v1;
vector<vector<int> >::iterator v2;
for(v1 = vector1.begin(); v1 != vector1.end(); v1++)
{
for(v2 = vector2.begin(); v2 != vector2.end(); v2++)
{
if(*v1 == *v2)
{
vector1.erase(v1);
}
}
}
当我尝试运行它并调试Qt挂起时。我也想知道是否需要更改擦除内容:
vector1.erase(v1.begin(), v1.end());
任何有关“更好”的方式的建议都将有所帮助。我知道这些是一些大向量,其中有10个数字超过2个半百万元素。
提前谢谢
Idzireit
仍然解决问题。现在,我正在尝试Mark Ransom解决方案的派生产品。这是到目前为止我得到的:
#include "includes.h"
bool vec_less(vector<int> &v1, vector<int> &v2)
{
for(int i = 0; i < 10; i++)
{
if(v1[i] == v2[i])
{
i++;
}
if(v1[i] < v2[i])
return true;
else
return false;
}
return v1.size() <v2.size();
}
void dupfilter(vector<vector<int> > &aaperms, vector<vector<int> > &perms)
{
vector<vector<int> >::iterator v1 = aaperms.begin();
vector<vector<int> >::iterator v2 = perms.begin();
while(v1 != aaperms.end() && v2 != perms.end())
{
if(*v1 == *v2)
{
aaperms.erase(v1);
++v1;
++v2;
}
if(vec_less(*v1, *v2) == true)
++v1;
else
++v2;
}
return;
}
我只需要对1个向量进行排序。另一个按原样进行排序。 我现在用附加代码遇到的问题是找不到重复项。它确实会遍历每个向量一次,但是由于某种原因它没有找到重复项。我知道有些原因是因为尽管我遇到了严重的sigseg故障,但先前的尝试并对其进行了分类发现了它们。
我一直在努力地绕过自动和独特的领域,只是无法完全理解示例和我的(代码?方法?)相吻合。
Idzireit
答案 0 :(得分:7)
您的解决方案存在两个三个问题。
您的代码具有未定义的行为。删除项目时,迭代器无效。
您的代码具有很大的复杂性 o(n^2)
o(n^3)
。
从向量的中间删除项具有线性复杂度,因此对于大向量,应避免使用。这就是为什么我更正了2
点。
下面的代码具有o(n)
的时间复杂度,通常最好使用STL算法:
using Vec = std::vector<std::vector<int>>;
void removeItems(Vec& from, const Vec& itemsToRemove)
{
const std::unordered_set<Vec::value_type> items {
itemsToRemove.begin(),
itemsToRemove.end()
};
auto it =
std::remove_if(from.begin(), from.end(),
[&items](const auto &x){
return items.count(x) != 0;
});
from.erase(it, from.end());
}
您可以考虑将内部std::vector
替换为std::array
,因为正如您所描述的那样,它具有恒定的大小,这将减少内存碎片(应该提供额外的提升)。
using Vec = std::vector<std::array<int, 5>>;
答案 1 :(得分:3)
您选择的算法为O(n²),这意味着对于大型数据集,将需要很长时间。很容易看出您为什么认为它挂了。
如果您不关心排序,则可以对两个向量进行排序,以将其从O(n²)问题转换为O(n log n)。对它们进行排序后,您将同时浏览每个向量,并根据哪个小于另一个来增加索引。
如果您无法一次将整个数据集放入内存中,甚至可以通过从已排序的文件中读取来使用此方法。
bool vec_less(const vector<int>& v1, const vector<int>& v2)
{
for (int i = 0; i < v1.size() && i < v2.size(); i++)
{
if (v1[i] < v2[i])
return true;
if (v2[i] < v1[i])
return false;
}
return v1.size() < v2.size();
}
std::sort(vector1.begin(), vector1.end(), vec_less);
std::sort(vector2.begin(), vector2.end(), vec_less);
vector<vector<int> >::iterator v1 = vector1.begin();
vector<vector<int> >::iterator v1out = v1;
vector<vector<int> >::iterator v2 = vector2.begin();
while (v1 != vector1.end())
{
if (v2 == vector2.end() || vec_less(*v1, *v2))
{
if (v1out != v1)
*v1out = *v1;
++v1;
++v1out;
}
else if (vec_less(*v2, *v1))
++v2;
else // equal
{
++v1;
++v2;
}
}
vector1.resize(v1out - vector1.begin());