【问题标题】:Sorting set elements while respecting numbers?在尊重数字的同时对集合元素进行排序?
【发布时间】:2020-12-29 11:50:30
【问题描述】:

我知道 C++ std::set 保持其元素排序。如何在尊重数值的同时保持这些元素的排序?

我面临的问题是,如果我尝试添加元素K1K2K10,例如,在集合将它们排序为字符串之后,它们会得到以下顺序:

K1
K10
K2

但是,我希望它们按以下顺序排列:

K1
K2
K10

我该怎么做?

【问题讨论】:

  • 字典顺序会产生K1 K10 K2,所以你确实得到了正确的行为。如果你想忽略K,只比较它后面的数字,你应该让解释更清楚一点。

标签: c++ sorting c++11 set


【解决方案1】:

在这种情况下,该集合确实按字典顺序存储字符串 - 只是碰巧这不是您想要的顺序。相反,您希望排序在比较事物时以数字方式处理数字。

有几种方法可以做到这一点。这是一种方法,它通过将字符串中存在的每个数字视为单个实体来进行比较。

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;

以这种方式进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多