我已经宣布了一个结构:
struct data{
vector<string> att;
string ds;
};
现在设置一个存储来自多个数据元素的唯一数据
set<data> s;
基于不同的vector<string> att
和string ds
怎么做?
答案 0 :(得分:2)
如果不了解您希望如何比较结构,可以尝试以下方法:
struct data
{
vector<string> att;
string ds;
friend bool operator < (const data& lhs, const data& rhs)
{
if (std::lexicographical_compare(lhs.att.begin(), lhs.att.end(), rhs.att.begin(), rhs.att.end()))
{
return true;
}
else if (std::lexicographical_compare(rhs.att.begin(), rhs.att.end(), lhs.att.begin(), lhs.att.end()))
{
return false;
}
else
{
return lhs.ds < rhs.ds;
}
}
};
我对此解决方案不满意,因为它执行两次词典比较,这是低效的。希望有人会提出更好的解决方案。
基本思路是,对于每个成员,比较左边&lt;对。如果为true,则返回true,否则比较右&lt;剩下。如果为true,则返回false。否则,继续下一个成员。
答案 1 :(得分:0)
注意:您可以详细了解我用来比较事物的技巧(std::tie
)in Implementing comparison operators via 'tuple' and 'tie', a good idea?
std::string
和std::vector
已定义operator<
:for strings和for vectors。因此,我们可以将它们与std::tie
一起使用来创建临时std::tuple
(它只使用对数据成员的引用,它不会创建任何副本,因此它非常有效)进行比较
operator<
std::set
需要比较其对象,以便了解其独特之处以及如何对事物进行排序。它默认使用operator<
(通过std::less
)来执行此操作,因此如果您为您的类提供该运算符,它将使用它。像这样:
struct data{
vector<string> att;
string ds;
operator<(const data& other) {
// Be sure to #include <tuple> for std::tie
return std::tie(att, ds) < std::tie(other.att, ds);
// If you don't want to (or can't) use std::tie, you can do this:
// return att < other.att || (att == other.att && ds < other.ds);
}
};
std::set<data> my_set; // Now it works.
这将使用Compare
functor来比较两个data
个对象(而不是operator<
,因此我们不需要对其进行定义):
struct Compare {
bool operator()(const data& left, const data& right) const {
return std::tie(left.att, left.ds) < std::tie(right.att, right.ds);
// Again, if you don't want to (or can't) use std::tie, you can do this:
// return left.att < right.att || (left.att == right.att && left.ds < right.ds);
}
};
std::set<data, Compare> my_set; // Now it works.