以下代码应该删除向量中的重复值
例如,如果向量包含{1,5,3,3}
,则结果应为{1,5,3}
。
程序启动,我输入整数n*
。
但是,该程序会引发以下错误:
Debug assertion failed.Program:... \ include \ vector line:932 表达式:向量下标超出范围。
当我按重试时,visual c ++会显示一个新窗口:
" try.exe触发了一个断点"。
然后,在我点击“继续”后,会出现另一个错误:
调试断言失败!程序:... \ include \ vector line:933 表达式:"标准c ++库超出范围" &安培;&安培; 0
我的代码如下:
#include <iostream>
#include <vector>
using namespace std;
void removeDup (vector<int>& v);
int main()
{
vector<int> v;
int i,n;
cin>>n;
for(i=0;i<n;i++){
v[i]=rand()%10;
}
removeDup(v);
for(i=0;i<n;i++)
{
cout<<v[i];
}
system("pause");
}
void removeDup(vector<int>& v)
{
int i,j,size;
size=v.size();
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
if(v[i]==v[j])
v.erase(v.begin()+j);
}
}
}
答案 0 :(得分:5)
断言失败实际上是在告诉你到底发生了什么。你的向量是零大小的,并且你试图索引一个空的向量(这自然会访问超出范围的东西)。
operator[]
不会为像vector
这样的标准序列动态创建元素,例如某些语言中的关联数组或std::map
的情况。您传递给operator[]
的索引必须在[0, vector.size())
范围内,否则它将在调试中触发此超出范围的断言失败(对于已检查的实现)或在发布版本中触发潜在的段错误/访问冲突(基本上未定义的行为)。这是出于性能原因而完成的,因为否则需要在operator[]
中进行分支,这通常会破坏vector
所具有的与数组相当的索引性能(尽管有at
方法会抛出它具有分支开销。)
在这里,您需要使用填充构造函数预先调整向量的大小,例如:
int i,n;
cin>>n;
vector<int> v(n);
...
或者在使用operator[]
方法resize
访问它之前调整其大小:
vector<int> v;
int i,n;
cin>>n;
v.resize(n);
或使用push_backs
:
vector<int> v;
int i,n;
cin>>n;
// can use reserve here for a performance boost if desired
// since we know the memory capacity needed in advance.
for(i=0;i<n;i++){
v.push_back(rand()%10);
}
您的removeDup
功能还有另外一个问题。那个问题在于你循环遍历向量,好像它的大小没有改变,但是调用一个擦除方法,它会在每次迭代时减小它的大小。这也会调用超出范围的访问权限 - 也许你可以找出解决方案作为练习的一部分(我假设这是一个练习,因为std::unique
会做的伎俩)。这里要注意的第一件事可能是operator[]
没有为你动态创建元素。
答案 1 :(得分:0)
我给你另一种方法来解决这个问题。(你可以使用它)。
您可以在此处使用#include<set>
删除重复值,如下所示:
set<int>s;
s.insert(10);
int i,n;
cin>>n;
for(i=0;i<n;i++){
s.insert(rand()%10);
}
set<int>::iterator ii;
for(ii=s.begin();ii!=s.end();ii++)
cout<<*ii;