C++中与Python字典等价的结构是什么?

30

我目前正在编写一个带有人工智能的井字游戏程序,但是我在翻译这行代码(Python)时遇到了一些困难:

RANKS = dict([(4,3),                       # center  = 3
              (0,2),(2,2),(6,2),(8,2),     # corners = 2
              (1,1),(3,1),(5,1),(7,1)])    # sides   = 1

如何学习C++?

有什么建议吗?


如果您提供一些关于如何使用“RANKS”的上下文信息,那么您更有可能获得有用的帮助。 - Jeffrey Bosboom
可能是将Python字典翻译成C ++的重复问题。 - Trilarion
5个回答

50

在C ++中最接近的匹配是 std :: unordered_map<int,int>。 这是一个哈希表,将 int 键映射到 int 值。

#include <unordered_map>


std::unordered_map<int, int> RANKS = {
        { 4, 3 },
        { 0, 2 }, { 2, 2 }, { 6, 2 }, { 8, 2 },
        { 1, 1 }, { 3, 1 }, { 5, 1 }, { 7, 1 }
};

您可以使用operator[]访问元素,例如:

std::cout << RANKS[0] << std::endl; // prints "2"
注意,C++标准库还有一个名为std::map的类模板,它允许您创建一个类似但是有序的查找表std::map<int, int>,具有对数级别的查找和插入复杂度。但是Python的dict是哈希表,因此在行为方面,unordered_map更为相似。

如果我使用map而不是其他方法,会有什么区别吗? - Jenny Calisay
5
在这种情况下,主要的区别在于时间复杂度。std::map是一棵自平衡的二叉搜索树,而std::unordered_map则是一个哈希表。它们的查找分别为O(log N)和O(1),但如果你关心性能,应该使用两者来测试代码。 - juanchopanza
2
虽然这个答案在2014年是正确的,但未来的读者应该注意,自Python 3.6以来,dict插入有序的(参见此Stackoverflow答案)。因此,自2017年以来,std::map可能是最好的答案。 - scūriolus
@scūriolusgodo 点。 不幸的是,顺序与 std::map 不同,因为它按键排序而不是插入。稍后我会添加澄清。 - juanchopanza

4
您可以使用map或unordered_map实现此目的(它们也可以正常工作),但是考虑到您的键是一组密集的整数(即从0到N的所有整数),有更好的选择。
我可能会使用std :: array。它看起来像这样:
std::array <char, 9> vals = { 2, 1, 2, 1, 3, 1, 2, 1, 2 };

这样做几乎具有相同的语法和可观察行为,但通常会节省相当多的内存,也可能节省CPU时间。

2
在C++中,这将是一个std::unordered_map
#include <unordered_map>

std::unordered_map<int, int> dict
{
    {
        { 4, 3 },
        { 0, 2 }, { 2, 2 }, { 6, 2 }, { 8, 2 },
        { 1, 1 }, { 3, 1 }, { 5, 1 }, { 7, 1 }
    }
};

1
更像是一个unordered_map,不是吗? - juanchopanza
1
我可以在这里使用映射吗? - Jenny Calisay
1
正确的写法是 unordered_map 而不是 map - jamylak
@juanchopanza 没错,你说得对。当你指出每个对的第一个元素实际上是唯一的,并且对应于一个看起来像是1D数组索引的东西时,我也注意到了。 - Captain Obvlious

1
C++中与Python的dict相对应的是std::map。要使用类似的语法初始化一个map,请执行以下操作:
std::map<int,int> myMap = {{4,3},                       # center  = 3
                           {0,2},{2,2},{6,2},{8,2},     # corners = 2
                           {1,1},{3,1},{5,1},{7,1}};    # sides   = 1

请注意,这需要使用C++11。
如果您无法使用C++11,请使用Boost.Assign中的map_list_of。他们页面上的示例是:
using namespace boost::assign; // bring 'map_list_of()' into scope
std::map<int,int> next = map_list_of(1,2)(2,3)(3,4)(4,5)(5,6);

0

虽然“语言等效”可能类似于std::unordered_map,但您的用例可能更适合使用直接数组:

int RANKS[] = {2, 1, 2, 1, 3, 1, 2, 1, 2};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接