我正在尝试删除向量中的相同整数。我的目标是只复制一份。好吧,我写了一个简单的代码,但它无法正常工作。有人可以帮忙吗?提前谢谢。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int a = 10, b = 10 , c = 8, d = 8, e = 10 , f = 6;
vector<int> vec;
vec.push_back(a);
vec.push_back(b);
vec.push_back(c);
vec.push_back(d);
vec.push_back(e);
vec.push_back(f);
for (int i=vec.size()-1; i>=0; i--)
{
for(int j=vec.size()-1; j>=0; j--)
{
if(vec[j] == vec[i-1])
vec.erase(vec.begin() + j);
}
}
for(int i=0; i<vec.size(); i++)
{
cout<< "vec: "<< vec[i]<<endl;
}
return 0;
}
答案 0 :(得分:3)
请勿使用此列表。使用集合:
#include <set>
...
set<int> vec;
如果元素已经存在,这将确保您没有重复项。
答案 1 :(得分:2)
您的代码存在问题:
for(int j=vec.size()-1; j>=0; j--)
{
if(vec[j] == vec[i-1])
vec.erase(vec.begin() + j);
}
这将是j==i-1
的时间,这将会扼杀你的算法,并且会有i-1 < 0
的时间,所以你会得到一个超出边界的例外。
您可以做的是更改您的for循环条件:
for (int i = vec.size() - 1; i>0; i--){
for(int j = i - 1; j >= 0; j--){
//do stuff
}
}
这样,你的比较中的两个变量永远不会相同,你的指数总是至少为0.
答案 2 :(得分:2)
如果您需要保存数字的初始顺序,您可以使用帮助set<int>
结构创建一个删除重复项的函数:
void removeDuplicates( vector<int>& v )
{
set<int> s;
vector<int> res;
for( int i = 0; i < v.size(); i++ ) {
int x = v[i];
if( s.find(x) == s.end() ) {
s.insert(x);
res.push_back(x);
}
}
swap(v, res);
}
答案 3 :(得分:2)
其他人已经指出std::set
。这当然简单易行 - 但它可能相当慢(比std::vector
慢很多,主要是因为(如链接列表)它由单独分配的节点组成,通过指针链接在一起形成一个平衡的树 1
您可以(经常)使用std::unordered_set
代替std::set
来改进。这使用哈希表 2 而不是树来存储数据,因此它通常使用连续存储,并给出O(1)预期访问时间而不是树所期望的O(log N)
通常更快的替代方法是收集向量中的数据,然后对数据进行排序并使用std::unique
来消除重复项。当您有两个不同的操作阶段时,这往往是最好的:首先收集所有数据,然后您需要删除重复项。如果您经常在添加/删除数据之间交替,并且需要重复的免费设置,那么std::set
或std::unordered_set
之类的内容可以在任何时候保持集合而不重复,可能会更有用。
所有这些也会影响项目的订单。 std::set
始终维护按定义顺序排序的项目。使用std::unique
,您需要对数据进行显式排序。使用std::unordered_set
,您可以按任意顺序对项目进行排序,这些顺序既不是原始订单也不是已排序。
如果您需要维护原始订单,但没有重复,通常最终需要将数据存储两次。例如,当您需要添加新项目时,尝试将其插入std::unordered_set
,然后当且仅当成功时,将其添加到向量中。
从技术上讲,作为树的实现并不是严格要求的,但它是关于我能够满足要求的唯一可能性,并且我所知道的所有实现都基于树
同样,其他实现在理论上可能是可能的,但我所知道的所有实现都使用散列 - 但在这种情况下,暴露了足够多的实现,避免哈希表可能会更加困难。
答案 4 :(得分:2)
要删除重复项,首先对数组进行排序会更容易。下面的代码使用两种不同的方法来删除重复项:一种使用内置的C ++算法,另一种使用循环。
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
int a = 10, b = 10 , c = 8, d = 8, e = 10 , f = 6;
vector<int> vec;
vec.push_back(a);
vec.push_back(b);
vec.push_back(c);
vec.push_back(d);
vec.push_back(e);
vec.push_back(f);
// Sort the vector
std::sort(vec.begin(), vec.end());
// Remove duplicates (v1)
std::vector<int> result;
std::unique_copy(vec.begin(), vec.end(), std::back_inserter(result));
// Print results
std::cout << "Result v1: ";
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(cout, " "));
std::cout << std::endl;
// Remove duplicates (v2)
std::vector<int> result2;
for (int i = 0; i < vec.size(); i++) {
if (i > 0 && vec[i] == vec[i - 1])
continue;
result2.push_back(vec[i]);
}
// Print results (v2)
std::cout << "Result v2: ";
std::copy(result2.begin(), result2.end(), std::ostream_iterator<int>(cout, " "));
std::cout << std::endl;
return 0;
}
答案 5 :(得分:2)
范围的主体不得改变迭代的序列的大小。
你可以在push_back
之前删除重复项void push(std::vector<int> & arr, int n)
{
for(int i = 0; i != arr.size(); ++i)
{
if(arr[i] == n)
{
return;
}
}
arr.push_back(n);
}
... ...
push(vec, a);
push(vec, b);
push(vec, c);
...