在使用operator +连接两个向量之前,从<t>类型的向量中删除索引

时间:2017-10-31 22:56:02

标签: c++ vector erase

我的函数接收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 ==========

1 个答案:

答案 0 :(得分:3)

问题是你在这一行添加了两个迭代器:

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

这样的操作不存在:您只需要一个递增和解除引用的迭代器,或者在需要删除时转换为迭代器的递增整数偏移量。将后一种解决方案作为模板,您可以更改外部循环,使jsize_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_backO(1)摊销的时间内运行,这会将其减少到O(n^2)。你也可以摆脱newVectorTwo并将元素直接附加到newVectorOne并返回。你需要改变最外面的迭代来使用索引来解决迭代器失效问题。

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