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,开始;b
for(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
}