如何解决在尊重数字的同时对集合元素进行排序?
我知道C ++ std::set
将其元素排序。如何在尊重数值的同时使这些元素保持排序?
面临的问题是,例如,如果我尝试添加元素K1
,K2
和K10
,则在集合将它们排序为字符串之后,它们将获得以下顺序:
K1
K10
K2
但是,我希望它们按此顺序排列:
K1
K2
K10
我该怎么做?
解决方法
在这种情况下,集合确实按字典顺序存储字符串-碰巧这不是您想要的顺序。相反,您希望排序时比较事物时以数字方式对待数字。
有两种方法可以做到这一点。这是一种方法,其作用是将字符串中存在的每个数字视为一个实体,以进行比较。
struct NumericCompare {
bool operator()(const std::string& left,const std::string& right) {
std::istringstream lhs(left),rhs(right);
while (lhs.peek() != EOF && rhs.peek() != EOF) {
/* Do we see digits in either of these? */
if (std::isdigit(lhs.peek() || std::isdigit(rhs.peek()) {
/* If one is a digit and the other isn't,compare the
* characters as usual.
*/
if (!std::isdigit(lhs.peek()) || !std::isdigit(rhs.peek())) {
return lhs.peek() < rhs.peek();
}
/* Otherwise,we have two numbers. Read them both and compare
* them. Note: This assumes numbers are nonnegative and 64-bit,* which may not be true in your case.
*/
std::uint64_t leftN,rightN;
lhs >> leftN;
rhs >> rightN;
if (lhs != rhs) return lhs < rhs;
}
/* Neither are numbers. Compare as usual. */
auto leftC = lhs.get();
auto rightC = rhs.get();
if (leftC != rightC) return leftC < rightC;
}
/* At least one stream is empty. See if they both are. */
if (lhs.peek() == EOF && rhs.peek() == EOF) return false;
/* So exactly one of them is. lhs comes before rhs if it's empty. */
return lhs.peek() == EOF;
}
};
在这里,您可以制作类似
的内容std::set<std::string,NumericCompare> mySet;
进行比较。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。