【问题标题】:C++ set unique and orderC++设置唯一性和顺序
【发布时间】:2017-09-23 15:21:09
【问题描述】:

我想在set<Foo, FooComp>做独一无二的订购。

在下面的代码中,我希望 a 是唯一的,并按 b 和 c 排序。 所以,foo.afoo.bfoo.c 的顺序不同。

我该怎么做?

struct Foo {
    int a, b, c;
    Foo(int a, int b, int c) : a(a), b(b), c(c) {}
}

struct FooComp {
    bool operator() (const Foo& f, const Foo& s) const {
        if (f.pattern == s.pattern) {
            return false;
        }
        if (f.start == s.start) {
            return f.length < s.length;
        }
        return f.start < s.start;
    }
}

还是我使用其他 STL 或数据结构?

【问题讨论】:

  • 我考虑使用 map,a 作为键,(b, c) 作为值。但是,地图不是为这种情况设计的(我想)。

标签: c++ sorting set compare unique


【解决方案1】:

使用标准库集这是不可能的。

比较运算符与排序紧密耦合。

虽然在性能方面有点糟糕的解决方案,但您可以拥有一个包含所有对象的集合,仅使用以下“a”排序:

struct Foo {
    int a, b, c;
    Foo(int a, int b, int c) : a(a), b(b), c(c) {}
    bool operator<(const Foo& rhs) const {
        return a < rhs.a;
    }
    friend ostream& operator<<(ostream&, const Foo&);
};

然后,每当您想使用您独特的算法对其进行排序时,只需将其复制到一个向量中并根据您的需要对其进行排序:

vector<Foo> v;
std::copy(s.begin(), s.end(), std::back_inserter(v));
std::sort(v.begin(), v.end(), [](const Foo& lhs, const Foo& rhs){ return (lhs.b == rhs.b) ? lhs.c > rhs.c : lhs.b > rhs.b; });

已编辑

这实现了您在 Pastebin 示例中使用的逻辑。 整个样本here

【讨论】:

  • 这不像我想的那样工作。在这段代码 (pastebin.com/dCBpcQB2) 中,我期望 1, 2, 3 2, 3, 1 3, 5, 2 但结果是 1, 2, 3 2, 3, 1 3, 5, 2 1, 5, 7
  • 如果您能告诉我们更多关于您将如何使用它的信息,也许我可以提供更多帮助...此解决方案可能缺乏性能,但功能不强。
【解决方案2】:

在 boost 中有一个现成的库来处理这种事情,叫做 boost.multi_index。

它允许声明一个满足多个索引及其约束的容器。

它有点过时,可以用一些爱来做,但它确实可以。

你可以这样开始:

struct Foo {
    int a, b, c;
    Foo(int a, int b, int c) : a(a), b(b), c(c) {}
};

#include <tuple>
#include <type_traits>
#include <utility>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>


struct get_a
{
    using result_type = int const&;
    result_type operator()(Foo const& l) const {
        return l.a;
    }
};

struct get_bc
{
    using result_type = std::tuple<int const&, int const&>;

    result_type operator()(Foo const& l) const {
        return std::tie(l.b, l.c);
    }
};

namespace foo {
    using namespace boost;
    using namespace boost::multi_index;

    struct by_a {};
    struct by_bc {};

    using FooContainer = 
multi_index_container
<
    Foo,
    indexed_by
    <
        ordered_unique<tag<by_a>, get_a>,
        ordered_non_unique<tag<by_bc>, get_bc>
    >
>;
}

int main()
{
    foo::FooContainer foos;

    foos.insert(Foo{ 1, 2,3 });
    foos.insert(Foo{ 2, 2,4 });

}

【讨论】:

  • 哇,非常感谢,但是我的环境不允许使用 boost 库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
相关资源
最近更新 更多