使用具有结构的 STL 向量上的唯一内容
在编程任务中,我试图确保特定向量仅包含唯一的项目。对于原始类型,操作非常简单:
vector<int> lala;
lala.push_back(1);
lala.push_back(99);
lala.push_back(3);
lala.push_back(99);
sort(lala.begin(), lala.end()); // lala: 1, 3, 99, 99
lala.erase(unique(lala.begin(), lala.end()), lala.end()); // lala: 1, 3, 99
但是,问题是我没有使用 int。但是:
typedef struct
{
int x;
int y;
int maxX;
int maxY;
int width;
int height;
int id;
} Rect;
bool SameRect(Rect first, Rect second)
{
return first.x == second.x &&
first.y == second.y &&
first.width == second.width &&
first.height == second.height &&
first.maxX == second.maxX &&
first.maxY == second.maxY;
}
//...
vector<Rect> lala;
//...
sort(lala.begin(), lala.end());
lala.erase(unique(lala.begin(), lala.end(), SameRect), lala.end());
//...
实际上不起作用。我做错了什么?
编辑:
根据某人的建议,我为 std::sort() 实现了两个排序谓词:
bool SortRect(const Rect &first, const Rect &second)
{
if (first.x < second.x) return true;
if (first.x > second.x) return false;
if (first.y < second.y) return true;
if (first.y > second.y) return false;
if (first.maxX < second.maxX) return true;
if (first.maxX > second.maxX) return false;
if (first.maxY < second.maxY) return true;
if (first.maxY > second.maxY) return false;
if (first.width < second.width) return true;
if (first.width > second.width) return false;
if (first.height < second.height) return true;
if (first.height > second.height) return false;
if (first.id < second.id) return true;
if (first.id > second.id) return false;
return false;
}
但我发现它具有相同的效果:
bool SortRect(const Rect &first, const Rect &second)
{
return first.x < second.x;
}
如果 SGI 的文档有任何内容。更短、简单的排序谓词也应该有效。我的测试已经证实了这一点(尽管我还没有尝试所有可能的组合)。
In a programming task, I'm trying to ensure a particular vector contains only unique items. With primitive types, the operation is as simple as:
vector<int> lala;
lala.push_back(1);
lala.push_back(99);
lala.push_back(3);
lala.push_back(99);
sort(lala.begin(), lala.end()); // lala: 1, 3, 99, 99
lala.erase(unique(lala.begin(), lala.end()), lala.end()); // lala: 1, 3, 99
However, the problem is I'm not using int. But:
typedef struct
{
int x;
int y;
int maxX;
int maxY;
int width;
int height;
int id;
} Rect;
bool SameRect(Rect first, Rect second)
{
return first.x == second.x &&
first.y == second.y &&
first.width == second.width &&
first.height == second.height &&
first.maxX == second.maxX &&
first.maxY == second.maxY;
}
//...
vector<Rect> lala;
//...
sort(lala.begin(), lala.end());
lala.erase(unique(lala.begin(), lala.end(), SameRect), lala.end());
//...
Doesn't really work. What did I done wrong?
EDIT:
With sth's advice, I implemented two sorting predicate for std::sort():
bool SortRect(const Rect &first, const Rect &second)
{
if (first.x < second.x) return true;
if (first.x > second.x) return false;
if (first.y < second.y) return true;
if (first.y > second.y) return false;
if (first.maxX < second.maxX) return true;
if (first.maxX > second.maxX) return false;
if (first.maxY < second.maxY) return true;
if (first.maxY > second.maxY) return false;
if (first.width < second.width) return true;
if (first.width > second.width) return false;
if (first.height < second.height) return true;
if (first.height > second.height) return false;
if (first.id < second.id) return true;
if (first.id > second.id) return false;
return false;
}
But I found that it has the same effect as:
bool SortRect(const Rect &first, const Rect &second)
{
return first.x < second.x;
}
if SGI's documentation is anything to come by. The shorter, simple sorting predicate should work as well. My test has confirmed this (Although I have not try all possible combinations).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您还必须定义一个比较函数,
sort()
应该使用该函数对矩形进行排序。这个比较函数应该实现严格弱排序,以便相等的元素最终在向量中彼此相邻。如果向量未排序,
unique()
将找不到未排序的重复元素。You also have to define a comparison function that should be used by
sort()
to sort the Rects. This comparison function should implement a strict weak ordering so that equal elements end up next to each other in the vector.If the vector is not sorted,
unique()
will not find the unsorted duplicate elements.为什么不使用
std::set
首先?其内容保证是唯一的。旁注:
您不需要在 C++ 中
typedef
结构,只需struct Rect {};
就足够了。您的比较函数应该通过 const 引用(即
const Rect&
)获取其参数,因为它不需要修改它们,也不需要副本。Why don't you use
std::set
in the first place? Its contents are guaranteed to be unique.Sidenotes:
You don't need to
typedef
structs in C++, juststruct Rect {};
is sufficient.Your comparison function should take its parameters by const-reference (i.e.
const Rect&
) as it doesn't need to modify them and doesn't need copies.sort(lala.begin(), lala.end());
std::sort
如何知道如何对Rect
进行排序?适当地?定义一个比较函数并将其作为第三个参数传递,就像您对std::unique
所做的那样。它必须采用两个 Rect 作为参数,如果第一个Rect
小于则返回 true。第二个。例如:
请注意,我将 Rect 作为 const 引用传递,您似乎在示例中忘记了这一点。
sort(lala.begin(), lala.end());
How would
std::sort
know how to sort yourRect
s? properly? Define a comparison function and pass it as third parameter, as you did forstd::unique
. It must take twoRect
s as parameters and returns true if the first is < the second.For example:
Note that I'm passing the
Rect
's as const references, you seem to have forgotten this in your sample.这就是我想到的:
我在排序函数中添加了一个谓词:
但我发现它具有相同的效果:
那么是不是像所说的那样,我只需要对第一个元素进行排序(对于唯一的函数工作正常)?
This is what I come up with:
I added a predicate to the sorting function:
But I found that it has the same effect as:
So is it like sth said, I just need to sort only the first element (for the unique function to work properly)?
我不确定你想要实现什么,但一般来说,正如所指出的,你需要设计你的矩形的比较。是什么使得一个矩形在序列中排在另一个矩形之前。
最简单的变体之一是在 x 坐标上进行比较。更复杂的选项是根据为矩形计算的希尔伯特值进行排序。请参阅问题计算 希尔伯特 R 树中使用的点的希尔伯特值?
也许您正在研究某种空间索引,然后了解R 树
I'm not sure what you are trying to implement, but generally as it's been pointed, you need to design what's your comparison of your rectangles. What makes one rectangle ordered before another one in a sequence.
One of the simplest variant is to compare on the x-coordinate. More sophisticated option is to sort according to Hilbert value calculated for rectangle. See question Calculate the Hilbert value of a point for use in a Hilbert R-Tree?
Perhaps you're working on some sort of spatial index, then learn about R-tree