如何从c ++中的向量中删除重复项(带有原始值)

时间:2018-05-28 12:38:29

标签: c++ stl

我编写了程序来删除给定数字集中的重复项。但我没有获得所需的输出。相反,我每次都会收到SIGSTP运行时错误。输入/输出格式是这样的:       输入:1 2 5 7 1 4 2       输出:5 7 4 我的代码如下:

#include <iostream>
#include<string>
#include <vector>
using namespace std;

int main() {
    // your code goes here
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        vector<int> v_num;
        for(int i=0;i<n;i++)
        {
            int x;
            cin >> x;
            v_num.push_back(x);
       }
       vector<int>::iterator it;
       for(it=v_num.begin();it!=v_num.end();)
       {
           int val=*it;
           int flag=0;
           vector<int>:: iterator j;
           for(j=it+1;j!=v_num.end();)
           {
               if(val==*j)
               {
                   v_num.erase(j);
                   flag=1;
               }
               if(flag==0)
                  j++;
           }
           if(flag==1)
                { v_num.erase(it);
                 flag=1;}
           if(flag==0)
                 it++;
       }

        for(int i=0;i<v_num.size();i++)
           { cout <<v_num[i]<<endl;
            }
    }

}

这是我在线平台上的第一个问题,所以有时我可能不清楚。在这种情况下,任何建议或进一步澄清都可以在评论部分发布。提前谢谢。

3 个答案:

答案 0 :(得分:2)

您的代码的问题是您擦除元素并稍后使用迭代器。

e.g。

       for(j=it+1;j!=v_num.end();)
       {
           if(val==*j)
           {
               v_num.erase(j);

我只是从您的代码中复制并粘贴它。您删除j以及再次使用it的下次迭代,这很可能无效

从向量中擦除使迭代器无效。

这是您应该使用std::list代替std::vector

的情况之一

答案 1 :(得分:1)

你真的不应该使用这样的矢量。从向量中间删除会导致它每次都重新分配以下所有值。此时所有迭代器都变为无效,这可能会导致运行时错误。

简而言之,当您在向量上调用erase时,迭代器itj都将变为无效,并且不应使用。

您可以使用std::unique或仅使用std::set来存储唯一值,从而避免向量一起使用,因为您正在读取上面几行的值。

答案 2 :(得分:0)

你可能需要这样的东西

vector<int> vec{1,1,2,3,4,4,2,5,6};
sort(begin(vec), end(vec));
auto last = unique(begin(vec), end(vec));
vec.erase(last, end(vec));

要使std :: unique工作,应事先对范围进行分类

编辑: 我看到我没有完成所需要的问题,因为我正在寻找其他答案。我设法编写一个函数来返回一个具有唯一数字的向量,但它分配临时计数数组并最终从向量中复制唯一的元素。对此有任何意见。

template<typename T>
std::vector<T> erase_duplicated(const std::vector<T>& vec)
{
    const size_t n = vec.size();
    int* duplicates = new int[n];
    for(size_t i = 0; i < n; ++i) duplicates[i] = 0;

    for(size_t i = 0; i < n; ++i)
    {
        for(size_t j = i + 1; j < n; ++j)
            if(vec[i] == vec[j])
            {
               ++duplicates[i];
               ++duplicates[j];
            }
    }
    std::vector<T> temp;
    for(size_t i = 0; i < n; ++i)
    {
        if(!duplicates[i])
            temp.push_back(vec[i]);
    }
    delete [] duplicates;
    return temp;
}