【问题标题】:C++ map set hybridC++ 地图集混合
【发布时间】:2019-06-18 12:36:45
【问题描述】:

我有文件夹信息

struct folder
{
    int id;
    int folder_count;
    long long size;
};

我需要保留文件夹(可以是1000个或更多),分别按它们的folder_count和大小排序(folder_count最多的文件夹必须放在第一位,如果有相同的folder_count,则需要按大小排序) .

我已经通过自定义比较器实现了它

struct folder_comparator
{
    bool operator() (const folder& a, const folder& b) const 
    {
        return a.folder_count>b.folder_count || (a.folder_count==b.folder_count && a.size>=b.size);
    }  
};

并将文件夹放入集合中

set <folder, folder_comparator> folders;

但与此同时,文件夹会获得许多更新。我可以通过map 来实现这一点,密钥是文件夹的id

map<int, folder> folders;

但在这种情况下,我无法保持自定义订单(如上所述)。

两个都需要。 (保持自定义顺序和O(1) 或至少O(log(N)) 复杂性搜索)

在这种情况下,什么数据结构或集合和映射的混合可以帮助我?

【问题讨论】:

  • folder_comparator 不满足严格弱排序的要求,因此您的程序表现出未定义的行为。除其他问题外,它声明f 小于f,对于任何folder f。将&gt;= 更改为&gt;
  • @Elbek 比较器不起作用。它打破了比较器的一条规则,即它们必须在给定两个相同参数的情况下返回 false。您只需将&gt;= 更改为&gt; 即可解决此问题,就这样做吧。
  • 当您说“文件夹有很多更新”时,您的意思是它的folder_count 和/或size 可能会改变吗?在这种情况下,您不能将它们存储在set&lt;folder&gt; 中。或者至少,每当您需要更改这些内容时,您都需要从集合中删除该文件夹,对其进行更新,然后重新插入。
  • 未定义的行为永远不会与代码的其他部分无关
  • 我可能会同时拥有map&lt;int, folder&gt;set&lt;int, my_comparator&gt;set&lt;map&lt;int, folder&gt;::iterator, my_comparator&gt;my_comparator 将采用两个 ID 或两个迭代器,在地图中查找相应的文件夹并进行比较。同样,请记住,每当您更改影响顺序的文件夹的任何成员时,删除 ID/迭代器并将其重新插入集合中。

标签: c++ algorithm dictionary set


【解决方案1】:

两个都需要。 (保持自定义顺序和 O(1) 或至少 O(log(N)) 复杂度搜索)

这意味着Boost Multi-Index 很可能会完美地满足您的需要,使用 id 上的散列索引和使用(固定)比较器的非唯一排序索引。虽然它有学习曲线,但在你的情况下它似乎会更糟(而不是维护 2 个独立的容器)

PS 你当前的比较器不满足严格弱排序的要求,这是所有排序标准和增强容器的一部分。无论哪种情况,您都需要修复它。提供适当比较器的最简单方法是使用std::tie

bool operator() (const folder& a, const folder& b) const 
{
    return std::tie( a.folder_count, a.size ) > std::tie( b.folder_count, b.size );
}  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2011-11-01
    • 2016-08-13
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多