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

时间:2011-08-24 17:53:33

标签: c++ arrays sorting stl-algorithm

我有一系列结构;数组的大小为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.

这里有什么问题?

4 个答案:

答案 0 :(得分:6)

您可以结合使用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

希望这有帮助!

答案 1 :(得分:1)

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成语。

答案 2 :(得分:0)

您可以使用flyweight pattern。最简单的方法是使用Boost Flyweight library.

编辑:我不确定是否有某种方法可以找出Boost flyweight实现存储了多少对象,如果有的话,我似乎无法在文档。

答案 3 :(得分:0)

将算法应用于数组的另一种方法是将其元素插入std::set。这种方式是否合理取决于您打算如何使用您的物品。