微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 C++ 中删除 Vector 中的元素及其重复项

如何解决在 C++ 中删除 Vector 中的元素及其重复项

我在 Internet 上搜索过并知道如何删除元素(使用 std::erase)并找到元素的重复项然后将其删除vec.erase(std::unique(vec.begin(),vec.end()),vec.end());)。但所有方法都只删除一个元素或其重复项。

我想删除两个。

例如,使用这个向量: std::vector<int> vec = {2,3,1,5,2,1};

我希望输出为: {3}

我最初的想法是:

void removeDuplicatesandElement(std::vector<int> &vec)
{
    std::sort(vec.begin(),vec.end());
    int passednumber = 0;  //To tell amount of number not deleted (since not duplicated)
    for (int i = 0; i != vec.size(); i = passednumber)    //This is not best practice,but I tried
    {
        if (vec[i] == vec[i+1])
        {
            int ctr = 1;
            for(int j = i+1; j != vec.size(); j++)
            {
                if (vec[j] == vec[i]) ctr++;
                else break;
            }
            vec.erase(vec.begin()+i,vec.begin()+i+ctr);
        }
        else passednumber++;
    }
}

它奏效了。但是这段代码是多余的,运行时间为 O(n^2),所以我正在尝试寻找其他方法解决问题(可能是我从未听说过的 STL 函数,或者只是改进代码)。>

解决方法

可能是这样的:

array

Demo

这在很大程度上依赖于 void removeDuplicatesandElement(std::vector<int> &vec) { if (vec.size() <= 1) return; std::sort(vec.begin(),vec.end()); int cur_val = vec.front() - 1; auto pred = [&](const int& val) { if (val == cur_val) return true; cur_val = val; // Look ahead to the next element to see if it's a duplicate. return &val != &vec.back() && (&val)[1] == val; }; vec.erase(std::remove_if(vec.begin(),vec.end(),pred),vec.end()); } 保证具有连续存储的事实。它不适用于任何其他容器。

,

您可以使用 STL 映射进行操作,如下所示:

#include <iostream>
#include <vector>
#include <unordered_map>


using namespace std;

void retainUniqueElements(vector<int> &A){
    unordered_map<int,int> Cnt;
    for(auto element:A) Cnt[element]++;
    A.clear();  //removes all the elements of A
    for(auto i:Cnt){
        if(i.second == 1){   // that if the element occurs once
            A.push_back(i.first);  //then add it in our vector
        }
    }
}

int main() {
    vector<int> vec = {2,3,1,5,2,1};
    retainUniqueElements(vec);
    
    for(auto i:vec){
        cout << i << " ";
    }
    cout << "\n";

    return 0;
}

输出:

3 

上述方法的时间复杂度: O(n)

上述方法的空间复杂度: O(n)

,

根据您搜索的内容,我们可以在向量中查找重复值,然后使用 Erase–remove idiom 清理向量。

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

void removeDuplicatesandElement(std::vector<int> &vec)
{
    std::sort(vec.begin(),vec.end());

    if (vec.size() < 2)
        return;

    for (int i = 0; i < vec.size() - 1;)
    {
        // This is for the case we emptied our vector
        if (vec.size() < 2)
            return;

        // This heavily relies on the fact that this vector is sorted
        if (vec[i] == vec[i + 1])
            vec.erase(std::remove(vec.begin(),(int)vec[i]),vec.end());
        else
            i += 1;
    }

    // Since all duplicates are removed,the remaining elements in the vector are unique,thus the size of the vector
    // But we are not returning anything or any reference,so I'm just gonna leave this here
    // return vec.size()
}

int main()
{
    std::vector<int> vec = {2,1};
    removeDuplicatesandElement(vec);

    for (auto i : vec)
    {
        std::cout << i << " ";
    }
    std::cout << "\n";

    return 0;
}

输出:3

时间复杂度:O(n)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。