<T> 在使用运算符+ 连接两个向量之前从类型向量中删除索引

remove index from vector of type <T> before concatenating two vectors with operator+

本文关键字:向量 两个 索引 删除 类型 gt lt 连接 运算符      更新时间:2023-10-16

my 函数接收 2 个向量,比较每个向量中的元素是否存在重复项。如果发现重复项,我想从第二个向量中删除该元素。

调用擦除方法时出现编译器错误。我相信这是因为Vector<T>vector<int>::iterator类型不同,但我不确定如何解决这个问题。

有人可以建议我将如何解决这个问题吗?

template <typename T>
std::vector<T> operator+(const std::vector<T>& v1, const std::vector<T>& v2)
{
typename std::vector<T> newVectorOne = v1;
typename std::vector<T> newVectorTwo = v2;
for (std::vector<int>::const_iterator i = newVectorOne.begin(); i != newVectorOne.end(); i++)
{
for (std::vector<int>::const_iterator j = newVectorTwo.begin(); j != newVectorTwo.end(); j++)
{
if (*i == *j)
{
newVectorTwo.erase(newVectorTwo.begin() + j); //error here
}
}
}
newVectorOne += NewVectorTwo;
return newVectorOne;
}

错误日志:

1>------ Build started: Project: Assignment2, Configuration: Debug Win32 ------
1>main.cpp
1>c:usersrmdocumentscomp3512_2assignmentsassignment2assignment2.h(67): error C2678: binary '+': no operator found which takes a left-hand operand of type 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>' (or there is no acceptable conversion)
1>        with
1>        [
1>            _Ty=int
1>        ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.11.25503includevector(332): note: could be 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>> std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>::operator +(int) const'
1>        with
1>        [
1>            _Ty=int
1>        ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.11.25503includevector(361): note: or       'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>> std::operator +<std::_Vector_val<std::_Simple_types<_Ty>>>(int,std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>)'
1>        with
1>        [
1>            _Ty=int
1>        ]
1>c:program files (x86)microsoft visual studio2017communityvctoolsmsvc14.11.25503includevector(243): note: or       'std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<_Ty>>> std::operator +<std::_Vector_val<std::_Simple_types<_Ty>>>(int,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>)'
1>        with
1>        [
1>            _Ty=int
1>        ]
1>c:usersrmdocumentscomp3512_2assignmentsassignment2assignment2.h(67): note: while trying to match the argument list '(std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>, std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>)'
1>        with
1>        [
1>            _Ty=int
1>        ]
1>c:usersrmdocumentscomp3512_2assignmentsassignment2main.cpp(36): note: see reference to function template instantiation 'std::vector<int,std::allocator<_Ty>> operator +<int>(const std::vector<_Ty,std::allocator<_Ty>> &,const std::vector<_Ty,std::allocator<_Ty>> &)' being compiled
1>        with
1>        [
1>            _Ty=int
1>        ]
1>Done building project "Assignment2.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

问题是您在此行中将两个迭代器一起添加:

newVectorTwo.erase(newVectorTwo.begin() + j); //error here

这样的操作不存在:您只需要一个递增和取消引用的迭代器,或者一个递增的整数偏移量,在需要删除时将其转换为迭代器。将后一种解决方案作为模板,您可以更改外部循环,以便jsize_t并从 0 变为newVectorTwo.size()(排除)。

请记住,erase也会擦除点及其后使迭代器失效,因此,如果内部循环实际擦除了任何内容(最后一个元素除外,因为在这种情况下,循环会立即退出),则您的内部循环是未定义的行为) - 因此使用j作为递增迭代器的方法通常不会像您那样工作。在vector中使用索引可以解决这个问题:除了begin()创建的临时迭代器之外,您根本没有对迭代器的引用。

性能

对于任何显著大小的载体,解决方案的性能都将非常差。两个嵌套循环和erase调用使其成为O(n^3)解决方案(更具体地说,如果v1v2的大小分别为mn,则更具体地说O(m*n^2))。

更简单的解决方案是创建最初为空newVectorTwo,然后添加每个元素,其中没有重复项push_back,而不是尝试从完全填充的向量中删除重复项。此push_back在摊销时间内运行O(1),这将减少到O(n^2)。您也可以删除newVectorTwo并将元素直接附加到newVectorOne并返回。不过,您需要更改最外层的迭代以使用索引,以解决迭代器失效的问题。

如果需要预期的O(n)(实际上是O(n + m))解决方案,则可以使用v1的内容填充std::unordered_map并将其用于查找,而不是使用两个嵌套循环。