微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 C++ 中创建递归嵌套哈希图?

如何解决如何在 C++ 中创建递归嵌套哈希图?

def recursiveDict():
   return collections.defaultdict(recursiveDict)

# I can create a dictionary like the following
dic = recursiveDict()
dic['a'] = 1
dic['a']['a'] = 1
dic['a']['a']['a'] = 1
dic['a']['a']['a']['a'] = 1
and so on....

在使用 Python 和其他动态语言工作了 4 年后,我又回到了 C++ 工作。我希望能够使用 unordered_map 或 map 类创建一个递归嵌套列表(如上面 Python 代码中所示的列表)。

我找不到办法做到这一点。

我想要实现的是键应该是char/string类型,但要插入的值应该是int类型。

请告诉我如何做到这一点。

我最接近的是这个

struct CharMap {
    std::unordered_map<char,CharMap> map;
} root_map;

and use it like

root_map.map['a'].map['b'];

但是我应该重载什么才能获得上述确切的语法?

提前致谢。

解决方法

既然您阐明了您熟悉运算符重载的基本概念,我将勾勒出您可以遵循的基本蓝图来实现此语法。

您的容器将实现一个 operator[] 重载,该重载返回一个辅助对象。假设您的容器名为 CharMap,毕竟说完了,您的容器存储了 int

class CharMap {

    struct key {

        key operator[](const std::string &);

        operator int();

        key &operator=(int n);
    };

public:

    key operator[](const std::string &);

};

这将允许,例如:

CharMap container;

container["A"]["B"]["C"]=5;

int n=container["D"]["E"]["F"};

CharMap::operator[] 返回一个 key 辅助对象。该对象还实现了自己的 operator[] 重载,该重载返回另一个 key。最后,key 对象实现了 operator= 重载以便您可以为其赋值,或者实现 operator int() 重载以从容器返回一个值。

很明显,key 会在内部存储一个指向它来自的 CharMap 容器的指针,以便它可以更新或从容器返回适当的值。 key 还在内部以零散的方式跟踪用于创建它的所有密钥。 CharMap::key 在内部记录第一个字符串。然后,它的 key::operator[] 返回另一个 key,它在内部记录原始字符串和另一个字符串。

一旦 operator[]operator int() 被调用,它们将使用所有累积的字符串来完成他们的工作,以某种形式或方式,您需要弄清楚。

还有一些效率问题可能会也可能不会解决。这种方法实现了您想要的语法,但根据您的情况,可能需要进行一些微调来优化底层实现,以消除大量内部复制和改组。

此外,还需要一些额外的工作来实现正确的 const 正确性。但所有这些都只是实现细节,这就是您如何实现这种语法来访问由多个字符串索引的容器。

,

我希望能够创建一个递归嵌套列表(如上面 Python 代码中所示的列表)

我怀疑您是否真的想这样做。当然,我们不知道您尝试使用它的详细信息,但是:

  • 如果您希望关联结构以短字符串为键,请考虑使用 std::string 键,例如std::unoredered_map<std::string,int>
  • 如果您希望关联结构仅由 K 个字符序列作为键 - 使用 struct key { char[K] data; } 之类的东西作为键(并可能为该键类添加相关方法/转换运算符),或者 {{ 1}}。

我怀疑的是,您真的需要能够说“我正在部分应用密钥”,而且不能将一般哈希和部分密钥(例如字符串前缀)视为您的“子哈希图”。


PS - 如果性能是一个问题,请记住 std::unordered_map is rather slow。并且 std::array<char,K> 作为键也会减慢您的速度,因为它们通常将字符串数据存储在堆上,这意味着要进行大量的去/分配工作以及对堆上可能任意位置的访问。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。