从数组中删除唯一元素的最有效方法

时间:2017-10-19 10:28:45

标签: c++ arrays algorithm c++11 duplicates

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

给出的数组:

9, 4, 9, 3, 1, 4, 6, 6, 3, 6, 9, 1, 3    // all duplicates

输出:

filename

4 个答案:

答案 0 :(得分:3)

我可能会这样做:

#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";
}

输出结果为:

$ g++ test.cc -std=c++11 && ./a.out
9 4 9 3 1 4 6 6 3 6 9 1 3

这是两次传递,你建立了一个BST。如果您觉得这太慢了,可以尝试使用std::unordered_map构建直方图,它具有更好的插入和查找复杂性特征。

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

答案 1 :(得分:1)

我会使用C ++集,因为它们的对数复杂度(编辑:如Scheff所述)。

此解决方案具有O(n log n)算法复杂度:

#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;
}

答案 2 :(得分:0)

void rmdup(int *array, int length)
{
    int *current , *end = array + length - 1;

    for ( current = array + 1; array < end; array++, current = array + 1 )
    {
        while ( current <= end )
        {
            if ( *current == *array )
            {
                *current = *end--;
            }
            else
            {
                current++;
            }
        }
    }
}

//希望这有助于你

答案 3 :(得分:0)

这个怎么样?

#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;
}

只有一个通行证。