如何用自定义比较表示一组指针但保持原始原始指针重复比较

时间:2013-11-21 08:19:30

标签: c++ pointers set

基本上,我想保存一组指针,这些指针应该按我的自定义比较函数排序,但唯一性仍应由指针本身决定。

然而:

#include <iostream>
#include <string>
#include <set>
#include <utility>
#include <functional>
using namespace std;

//         count, word
typedef pair<int, string> WordFreq;

struct WordFreqPointerCmp
{
    bool operator()(const WordFreq* lhs, const WordFreq* rhs) const
    {
        return lhs->first > rhs->first;
    }
};

int main()
{
    set<WordFreq*, WordFreqPointerCmp> s;
    s.insert(new WordFreq(1, "word1")); // Inserted
    s.insert(new WordFreq(1, "word2")); // This is not inserted
    s.insert(new WordFreq(3, "word3")); // Inserted

    cout << s.size() << endl;

    for (set<WordFreq*, WordFreqPointerCmp>::iterator it = s.begin();
         it != s.end(); ++it)
    {
        cout << (*it)->second << ": " << (*it)->first << endl;
    }

    return 0;
}
/* Output:
2
word3: 3
word1: 1
 */

正如您所看到的那样,顺序是正确的,但重复测试是错误的。我想做的是:

  • 如需订购,我想使用WordFreqPointerCmp;
  • 对于重复测试,我想使用原始指针比较的原始含义,即地址比较,这意味着,即使下面的集合中也应该有两个条目;

    set<WordFreq*, WordFreqPointerCmp> s;
    s.insert(new WordFreq(1, "word1"));
    s.insert(new WordFreq(1, "word1"));
    

我也尝试了以下内容,但结果相同:

template<>
struct greater<WordFreq*>
{
    bool operator()(WordFreq* const& lhs, WordFreq* const& rhs) const
    {
        return lhs->first > rhs->first;
    }
};
set<WordFreq*, greater<WordFreq*> > s;

2 个答案:

答案 0 :(得分:1)

虽然这篇文章很古老,但我刚刚面临同样的问题,所以它可能对某些人有帮助。

在您的代码中,您只处理一个值,但如果值相同则会怎样?然后set将其视为相同的元素。正确的解决方案是扩展比较功能,以提供有关如何测试重复项的附加信息。它可以像比较字符串一样随意,例如在你的情况下:

struct WordFreqPointerCmp
{
    bool operator()(const WordFreq* lhs, const WordFreq* rhs) const
    {
        if (lhs->first == rhs->first)
            return lhs->second > rhs->second;
        else
            return lhs->first > rhs->first;
    }
};

答案 1 :(得分:0)

我不确定问题是什么。由于您希望对中的第一个组件是确定唯一性的键,因此插入两个键值为1的“WordFreq”应该导致第二个组件驱逐第一个组件。结果符合期望值。

更新:我想,我误解了一些事情。由于您需要重复键,因此您可能正在寻找multimap

更新2 :为了完成这项工作,您需要在添加新对象之前添加一个步骤:迭代相同键的所有值,然后将这些值踢出要添加的对象。另外,我忘了提到multiset这可能是你更喜欢的。

我承认,这里是Java HashSet的单独订单和相等测试派上用场的地方。也许你可以找到它的C ++版本。