从数组中删除唯一元素的最有效方法 在C++中,从数组中剔除元素的有效方法是什么?

从数组中删除唯一元素的最有效方法 在C++中,从数组中剔除元素的有效方法是什么?,c++,arrays,algorithm,c++11,duplicates,C++,Arrays,Algorithm,C++11,Duplicates,给定的数组: 9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3 // keep duplicates, delete uniques 输出: 9, 4, 9, 3, 1, 4, 6, 6, 3, 6, 9, 1, 3 // all duplicates void rmdup(int*数组,int长度) { int*当前,*结束=数组+长度-1; 用于(当前=阵列+1;阵列我将使用C++集,因为它们的对数复杂性(编辑

给定的数组:

9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3    // keep duplicates, delete uniques
输出:

9, 4, 9, 3, 1, 4, 6, 6, 3, 6, 9, 1, 3    // all duplicates
void rmdup(int*数组,int长度)
{
int*当前,*结束=数组+长度-1;
用于(当前=阵列+1;阵列(当前< P>我将使用C++集,因为它们的对数复杂性(编辑:如所说)。< /P>
此解决方案的算法复杂度为O(n logn):

#include <set>
#include <iostream>

int main(int argc, char** argv) {
    int nums[] = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
    std::set<int> s;
    std::set<int> dups;

    for (int i = 0; i < 19; ++i)
        if (!s.insert(nums[i]).second)
            dups.insert(nums[i]);

    for (int i = 0; i < 19; ++i)
        if (dups.find(nums[i]) != dups.end())
            std::cout << " " << nums[i];
    std::cout << std::endl;

    return 0;
}
#包括
#包括
int main(int argc,字符**argv){
int nums[]={9,8,4,9,21,3,1,4,6,2,5,6,7,12,3,6,9,1,3};
std::集s;
std::设置DUP;
对于(int i=0;i<19;++i)
如果(!s.insert(nums[i])秒)
重复插入(nums[i]);
对于(int i=0;i<19;++i)
if(dups.find(nums[i])!=dups.end()

我可能会这样做:

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

int main(int argc, char* argv[]) {
    std::vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 
                             5, 6, 7, 12, 3, 6, 9, 1, 3};
    // build histogram
    std::map<int, int> counts;
    for (int i : nums) ++counts[i];
    // copy elements that appear more than once
    std::vector<int> result;
    std::copy_if(nums.begin(), nums.end(),
                 std::back_inserter(result), 
                 [&](int x){ return counts[x] > 1; });
    // print result
    for (int i : result) {
        std::cout << i << " ";
    }
    std::cout << "\n";
}
这是两个过程,您需要构建一个BST。如果您觉得这太慢,您可以尝试使用
std::unordered_map
构建直方图,它在插入和查找方面具有更好的复杂性特征

如果希望从原始向量中删除重复项,而不是构建另一个向量,则可以使用。(这是留给读者的练习。)

这是怎么回事

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

using namespace std;

int main(int argc, char** argv) {
    vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
    std::set<int> s;
    vector<int> dups;

    for(auto i:nums)
        if (!s.insert(i).second)
            dups.push_back(i);

    for_each(dups.begin(),dups.end(),[](int a){cout<<a<<" ";});
    cout << endl;

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,字符**argv){
向量nums={9,8,4,9,21,3,1,4,6,2,5,6,7,12,3,6,9,1,3};
std::集s;
矢量DUP;
用于(自动i:nums)
如果(!s.插入(i).秒)
重复。推回(i);

对于每个(dups.begin(),dups.end(),[](int a){couta loop with book keeping in a
std::set
std::unordered_set
@Jenin是否允许对原始数组进行排序?loop,将元素添加到
std::set
,如果尝试时元素已在集合中,则将其添加到重复项列表中。这是昨天才提出的问题……你至少应该尝试解决这个问题你的电脑有问题吗own@VladfromMoscow,不,不允许原始的与赋值相关的排序函数没有意义。一次通过,但输出与需要的不同使用
无序映射
而不是
映射
可以使它快一点“我认为你不会得到明显快一点的结果。”实际上,它可以用无序映射来完成。它不是O(n logn),而是O(n)。我认为这算是“明显更快”。@JimMischel虽然O(n)在理论上比O(n logn)快,但在实践中不一定明显快。(FWIW我删除了该部分,赞成在
std::unordered_映射上添加注释
)而
unordered_-map
的操作复杂度平均为
O(n)
而不是最坏的情况。@DAle:是的,
unordered_-map
的平均情况复杂度为O(n),最坏情况复杂度为O(n log n)。最糟糕的情况是,如果插入的项目都落在非常少的存储桶中。也就是说,大量的哈希冲突。如果没有特意生成的病理数据,我在实践中从未见过这种情况发生。
$ g++ test.cc -std=c++11 && ./a.out
9 4 9 3 1 4 6 6 3 6 9 1 3
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int main(int argc, char** argv) {
    vector<int> nums = {9, 8, 4, 9, 21, 3, 1, 4, 6, 2, 5, 6, 7, 12, 3, 6, 9, 1, 3};
    std::set<int> s;
    vector<int> dups;

    for(auto i:nums)
        if (!s.insert(i).second)
            dups.push_back(i);

    for_each(dups.begin(),dups.end(),[](int a){cout<<a<<" ";});
    cout << endl;

    return 0;
}