如何从C++数组中删除重复项

How do I remove duplicates from a C++ array?

本文关键字:删除 数组 C++      更新时间:2023-10-16

我有一个结构数组;阵列大小为N。

我想从数组中删除重复项;也就是说,执行一个就地更改,将数组转换为每个结构的单一外观。此外,我想知道新的大小M(缩减数组中的最高索引(。

结构包括基元,所以比较它们很简单。

我如何在C++中高效地做到这一点?

我已经实现了以下操作程序:

bool operator==(const A &rhs1, const A &rhs2) 
{       
    return ( ( rhs1.x== rhs2.x )  &&
             ( rhs1.y == rhs2.y ) );
}
bool operator<(const A &rhs1, const A &rhs2) 
{       
    if ( rhs1.x == rhs2.x )  
             return ( rhs1.y < rhs2.y );
    return ( rhs1.x < rhs2.x );
}

然而,我在运行时遇到了一个错误:

std::sort(array, array+ numTotalAvailable);
 * array will have all elements here valid.
std::unique_copy(
        array, 
        array+ numTotalAvailable, 
        back_inserter(uniqueElements)); 
 * uniqueElements will have non-valid elements.

这里怎么了?

您可以使用std::sortstd::unique算法的组合来实现这一点:

std::sort(elems.begin(), elems.end());                  // Now in sorted order.
iterator itr = std::unique(elems.begin(), elems.end()); // Duplicates overwritten
elems.erase(itr, elems.end());                          // Space reclaimed

如果您使用的是原始数组(而不是std::vector(,那么如果不将元素复制到新的范围,就无法实际回收空间。但是,如果您可以从一个原始数组开始,最后得到std::vectorstd::deque之类的东西,那么您可以使用unique_copy和迭代器适配器来复制唯一的元素:

std::sort(array, array + size); // Now in sorted order
std::vector<T> uniqueElements;
std::unique_copy(array, array + size,
                 back_inserter(uniqueElements)); // Append unique elements

在这一点上,uniqueElements现在拥有所有的唯一元素。

最后,为了更直接地解决您的初始问题:如果您想在适当的位置执行此操作,您可以通过使用unique的返回值来确定保留了多少元素来获得答案:

std::sort(elems, elems + N);                // Now in sorted order.
T* endpoint = std::unique(elems, elems + N);// Duplicates overwritten
ptrdiff_t M = endpoint - elems;             // Find number of elements left

希望这能有所帮助!

std::set<T>  uniqueItems(v.begin(), v.end());

现在uniqueItems只包含唯一项。用它做任何你想做的事情。也许,你希望v包含所有唯一的项目。如果是,则执行以下操作:

//assuming v is std::vector<T>
std::vector<T>(uniqueItems.begin(), uniqueItems.end()).swap(v);

现在v包含了所有的唯一项。它还将v缩小到最小大小。它利用了Shrink-to-fit成语。

您可以使用轻量级模式。最简单的方法是使用Boost Flyweight库。

编辑:我不确定是否有办法找出Boost轻量级实现存储了多少对象,如果有,我似乎在文档中找不到。

将算法应用于数组的另一种方法是将其元素插入std::set中。这样做是否合理取决于你计划如何使用你的物品。