我的函数接收2个向量,比较每个向量中的元素是否重复。如果找到重复,我想从第二个向量中删除该元素。
调用erase方法时出现编译器错误。我相信这是因为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:\users\rm\documents\comp3512_2\assignments\assignment2\assignment2.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 studio\2017\community\vc\tools\msvc\14.11.25503\include\vector(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 studio\2017\community\vc\tools\msvc\14.11.25503\include\vector(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 studio\2017\community\vc\tools\msvc\14.11.25503\include\vector(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:\users\rm\documents\comp3512_2\assignments\assignment2\assignment2.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:\users\rm\documents\comp3512_2\assignments\assignment2\main.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 ==========
答案 0 :(得分:3)
问题是你在这一行添加了两个迭代器:
newVectorTwo.erase(newVectorTwo.begin() + j); //error here
这样的操作不存在:您只需要一个递增和解除引用的迭代器,或者在需要删除时转换为迭代器的递增整数偏移量。将后一种解决方案作为模板,您可以更改外部循环,使j
为size_t
,并从0变为newVectorTwo.size()
(不包括)。
请记住,erase
也会使>>处的迭代器失效,并且在擦除点之后,如果它实际上擦除了任何内容(除了最后一个元素,那么你的内部循环是未定义的行为)在这种情况下,循环在紧接着之后退出) - 所以使用j
作为递增迭代器的方法通常不会像你拥有它那样工作。使用vector
中的索引解决了:除了由begin()
创建的临时文件之外,你根本没有对迭代器的引用。
对于任何大小的矢量,您的解决方案的性能都会非常差。两个嵌套循环和erase
调用使其成为O(n^3)
解决方案(如果O(m*n^2)
和v1
的大小v2
和{m
更具体地n
分别为{1}}。
一个更简单的解决方案就是创建newVectorTwo
最初为空,然后添加push_back
的每个元素 not 一个副本,而不是尝试删除重复项一个完全填充的矢量。此push_back
在O(1)
摊销的时间内运行,这会将其减少到O(n^2)
。你也可以摆脱newVectorTwo
并将元素直接附加到newVectorOne
并返回。你需要改变最外面的迭代来使用索引来解决迭代器失效问题。
如果您需要预期的O(n)
(实际O(n + m)
)解决方案,则可以使用std::unordered_map
的内容填充v1
并将其用于查找,而不是使用两个嵌套循环。