C++ 保持向量的值

C++ 保持向量的值,c++,C++,我在编写只保留副本的程序时遇到了问题,以下是我已经编写的内容: #include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v; for (int n; std::cin >> n;) {v.push_back(n); } std::sort(v.begin(),v.end());

我在编写只保留副本的程序时遇到了问题,以下是我已经编写的内容:

#include <iostream>
#include <vector>
#include <algorithm>


int main()
{
    std::vector<int> v;

    for (int n; std::cin >> n;) 
    {v.push_back(n); }
    std::sort(v.begin(),v.end());

    for(std::vector<int>::iterator b = v.begin();b<v.end();++b)
    {

        if(*b != *(b+1) )
        {
            v.erase(b);


        }

    }

    for(std::vector<int>::iterator i = v.begin();i < v.end();++i)
    {
        std::cout<<*i<<" ";
    }


}
例如,我所说的保留副本的意思是 输入:13 7 2 13 5 2 1 13 产出:2 13
如果代码不是那么完美,我很抱歉,我是一个完全的初学者。我希望您理解我的困难。

您试图取消对无效迭代器的引用。在第二个for循环的最后一次迭代中,*b+1将尝试取消引用此迭代器。 更改:

您正试图在当前迭代中删除迭代器。

从向量中删除时,指向已删除元素或向量中更高版本的所有迭代器都将失效。幸运的是,erase会将迭代器返回到被擦除元素之后的元素,因此您可以执行以下操作:

for(auto b = v.begin(), end=std::prev(v.end()); b != end;) {
    if(*b != *(b+1) ) b = v.erase(b);
    else              ++b;
}
注意,您需要在结束之前停止迭代一个元素,因为您需要*b+1

然而,上述内容并没有删除所有重复元素,而是删除其中一个

另一种方法是搜索不属于重复序列的第一个元素,如果没有重复则删除该元素,如果有重复则删除所有重复,但只有一个重复

我在下面的示例中使用了标准算法,但是您可以很容易地将其替换为执行相同操作的循环。只需搜索不等于*b的第一个元素


迭代器失效的典型案例。最好的办法是从向量的末尾到开始。你的意思是,切换开始和结束?哥们,你认为在你取出的元素之后,剩下的元素会发生什么变化?他们都回到一个地方。所以,++b将要做一些令人讨厌的事情。你需要拿出你的调试器,自己看看。3小时算不了什么。3年是博士学位。@Theooc试着用它来代替你擦除元素的循环。自动最后=v.开始;对于自动b=v,开始;bfor(std::vector<int>::iterator b = v.begin();b<v.end()-1;++b)
v.erase(b+1)
for(auto b = v.begin(), end=std::prev(v.end()); b != end;) {
    if(*b != *(b+1) ) b = v.erase(b);
    else              ++b;
}
#include <algorithm>

for(auto b = v.begin(); b != v.end();) {

    // find the first element not being a repetition of *b
    auto r = std::find_if_not(b + 1, v.end(), [&b](const auto& v) { return *b==v; });

    if(b + 1 == r) b = v.erase(b);        // *b had no repetitions, erase b
    else           b = v.erase(b + 1, r); // erase all repetitions except one element
}