2

在使用地图以分层方式组织数据时,我已经习惯了 Python 的开发思维方式。它很简单,语法上也很便宜。虽然在 C++ 中不是非常困难,但嵌套映射/集合使组织变得困难。我不认为我在考虑这个问题。

例如,我使用以下组织:

typedef set<Motif> Motifs;

typedef map<Motif, Motifs> LinkedMotifs;

struct Candidates {
    Motifs deadend;
    Motifs intralinked;
    LinkedMotifs interlinked;
};

typedef map<Linker::shp, Candidates> LinkedCandidates;

出于性能原因,我使用了 boost 的 flat_map/set 实现。Motif 是一个 std::pair 结构。Linker::shp 是一个 SharedPtr。

该地图是搜索功能的结果。搜索完成后,我对结果进行评分,并在一个单独的函数中将结果写入文件。我在设计项目时考虑到了函数式编程,最初的尝试是将候选结构和分数结构分开。然而,这产生了问题,因为我基本上最终在内存中重新创建了所有映射结构。当所有内容都写入磁盘时,结构很重要。

我可以将分数链接到地图和集合中的迭代器,但老实说,我似乎让事情变得太难了。

谢谢!

*经过编辑以使我的最终目标更有意义。

4

1 回答 1

3

请注意,代码的大部分冗长来自在所有名称中重复使用“序列和配置对”。这表明您需要一个术语来解决这个问题。最好是使用问题领域俚语中使用的相同术语来命名它。人类是懒惰的。可以说他们称之为motif,一切都变得简单多了:

typedef set<Motif> Motifs;

typedef map<Motif, Motifs> LinkedMotifs;

struct Candidates {
    Motifs deadend;
    Motifs intralinked;
    LinkedMotifs interlinked;
};

typedef map<Linker::shp, Candidates> LinkersCandidates;

IOW ...使用短名称。始终将每个名称放入 C++ 中的命名空间。C++ 通常用于编写相当大的产品(平均数百万行),这有助于避免名称冲突。

如果您需要重用该组织,那么您可以使用模板:

template<typename T>
struct Handler {
    typedef set<T> Ts;

    typedef map<T, Ts> LinkedTs;

    struct Candidates {
        Ts deadend;
        Ts intralinked;
        LinkedTs interlinked;
    };

    typedef map<Linker::shp, Candidates> LinkersCandidates;
};

typedef Handler<Motif>::LinkersCandidates LinkersMotifCandidates;
typedef Handler<Other>::LinkersCandidates LinkersOtherCandidates;

如果您在应该使用引用或指针的地方使用副本,或者您没有选择正确的容器,则可能会出现性能问题。例如,当sets 和maps 不够复杂时, Boost.MultiIndexBoost.Graph提供更复杂的容器。另一方面,当map或在set大多数情况下保持不可变时,然后vector对对(而不是map)或排序vector(而不是)进行排序,set并且std::lower_bound可能会提供更好的性能。复制sets 和maps 远比复制vectors 贵。

于 2013-06-17T00:33:23.030 回答