我有一系列结构;数组的大小为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.
这里有什么问题?
答案 0 :(得分:6)
您可以结合使用std::sort
和std::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::vector
或std::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
。这种方式是否合理取决于您打算如何使用您的物品。