【问题标题】:Is it possible to process equality in a std::set comparator?是否可以在 std::set 比较器中处理相等性?
【发布时间】:2014-11-22 11:03:54
【问题描述】:

很抱歉,如果标题描述性不够好,我很难弄清楚如何命名这个问题。这几乎是我第一次需要使用集合,尽管我一直在使用地图。

我不认为这是可能的,但我需要问。当我将结构添加到我的 std::set 时,我想对它执行特定操作,但前提是相等性为真。

例如,我可以使用一个列表,然后使用 sort() 和 unique() 列表。在我的谓词中,我可以随心所欲,因为如果 2 个值相等,我将得到结果。

下面是我的列表谓词的简单示例:

bool markovWeightOrdering (unique_ptr<Word>& w1, unique_ptr<Word>& w2) {
        if (w1->word_ == w2->word_) {
                w1->weight_++;
                return true;
        }
        return false;
}

有没有人知道如何获得类似的结果,同时使用 std::set 来明显提高性能(和简单性),因为我的容器无论如何都需要是唯一的?感谢您的任何帮助或指导,非常感谢。

【问题讨论】:

    标签: c++ c++11 set comparator predicate


    【解决方案1】:

    set 中的元素是不可变的,所以你不能修改它们。

    如果您将set 与指针(或类似)一起使用,则指向的对象可能会被修改(但注意不要修改顺序)。 std::set::insert 返回一个带有 iteratorpair 和一个判断元素是否已插入的布尔值,因此您可以执行以下操作:

    auto p = s.insert(make_unique<Word>("test"));
    if (p.second == false) {
        (*p.first)->weight += 1;
    }
    

    Live example

    【讨论】:

    • 因此,如果我使用重量订购我的套装...基本上我所做的确实是错误的。那么是否有另一个容器是搜索树,我可以修改里面的值?还是我在这里做梦? :)
    • 您可能对multi_index in boost感兴趣。
    • 不,请用 Boost 停止它。
    【解决方案2】:

    操作比较运算符可能是个坏主意。 您可以将 std::set 与谓词一起使用:

    struct LessWord
    {
        bool operator () (const std::unique_ptr<Word>& w1, const std::unique_ptr<Word>& w2) {
            return w1->key < w2->key;
        }
    };
    typedef std::set<std::unique_ptr<Word>, LessWord> word_set;
    

    比你在插入时测试单词是否存在并增加权重:

    word_set words;
    std::unique_ptr<Word> word_ptr;
    auto insert = words.insert(word_ptr);
    if( ! insert.second)
        ++(insert.first->get()->weight_);
    

    注意:从逻辑上讲,这样做会破坏 const 的正确性。集合元素是不可变的,但 unique_ptr 允许修改(甚至是键值的致命修改)。

    【讨论】:

    • 感谢您的回答!我标记另一个只是因为它更清楚插入的作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2012-08-31
    相关资源
    最近更新 更多