【问题标题】:std::set foreign key using custom comapratorstd::set 外键使用自定义比较器
【发布时间】:2021-12-15 10:51:00
【问题描述】:
std::vector<int> v = {1,1,1,1,2,2};
auto cmp = [&v](size_t a, size_t b){return v[a] < v[b];};
std::multiset<int, decltype(cmp)> s(cmp);

Vector v 的内容只是一个例子。它可以是任何整数数组,但可以有重复值。

我使用多重集是因为我希望能够按顺序遍历所有值,并且因为 v 中的值不是唯一的。

另外,我想知道其中是否包含某个值。 例如插入后:

s.insert(1);
s.insert(1);
s.insert(2);
s.insert(2);

我希望这个测试中present 的值是false

auto iter = s.find(3);
bool present = iter != s.end();

但是,这是真的,我想这是由于 set 的内部实现(AVL/RB-tree?)以及它如何使用比较器在内部搜索值。 虽然,我认为它应该比较最后一个值以确保它是它认为的那样。

是否有一种优雅的方式(无需额外的辅助数据结构)使其“理解”它不具有价值?

【问题讨论】:

  • 比较器功能是一定有问题的。试试auto cmp = [](int a, int b){ return a &lt; b; }; - 您不会将 indices 作为比较器函数的参数。您会在multimap 中获得两个值。

标签: c++ stl


【解决方案1】:

auto cmp = [&amp;v](size_t a, size_t b){return v[a] &lt; v[b];};

您在cmp 函数中比较v[a]v[b] 的值,而不是ab

所以,如果你有a = 2b = 1cmp函数将比较v[2] v[1],即11,那么它将返回false,即不是你想要的。

例如,如果你想写一个函数,用一个函数比较v[a]v[b],你会写什么?

bool compare(int a, int b)
{
    return v[a] < v[b];
}

bool compare(int a, int b)
{
    return a < b;
}

所以,你应该把它改成这样:

auto cmp = [](int a, int b){return a &lt; b;};

编辑:这是来自 Ted Lyngmo 的 demo

【讨论】:

  • 比较 v 中的值是有意的,因为我希望 a 由 v 排序。
  • @user1912594 我已经编辑了我的答案来解释我的意思。
【解决方案2】:

根据你的cmp比较器,123都是等效键(因为v[1]v[2]v[3]都是1),所以s.find(3) != s.end()是正确的,而不是特定于实现的。

听起来您希望根据cmp 进行排序,但根据默认的std::less&lt;int&gt; 进行成员资格测试。在这种情况下,单独使用 std::multiset 无法满足您的需求,因为它对两者都使用了一个比较器。

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    相关资源
    最近更新 更多