跳转至

访问 std::map 中的数据

再次,在讨论如何从结构中提取数据时,我会使用静态 std::map 定义。由于模板接受两个类型,我还会使用一些伪类型让事情更明显。以下是本节其余部分引用的 std::map 对象声明:

typedef int keyInt;
typedef int valInt;
std::map<keyInt, valInt> myMap;

有了这个声明,myMap 的结构变成:

struct mapItem {
    mapItem* left;
    mapItem* parent;
    mapItem* right;
    keyInt key;
    valInt value;
struct map {
    DWORD irrelevant;
    mapItem* rootNode;
    int size;
}
map* _map = (map*)mapAddress;

你可能需要一些重要算法来访问游戏中 std::map 结构的数据。首先,如果你只想看到所有数据,盲目遍历地图中的每个项目可能很有用。要顺序遍历,你可以编写这样的迭代函数:

void iterateMap(mapItem* node) {
    if (node == _map->rootNode) return;
    iterateMap(node->left);
    printNode(node);
    iterateMap(node->right);
}

遍历整个地图的函数会先读取当前节点,检查它是否是 rootNode。如果不是,它会向左递归,打印节点,然后向右递归。

要调用这个函数,你必须像这样传一个指向 rootNode 的指针:

iterateMap(_map->rootNode->parent);

不过,std::map 的目的是以可快速搜索的方式存储键控数据。当你需要根据特定键定位节点时,模仿内部搜索算法比扫描整棵树更可取。搜索 std::map 的代码看起来像这样:

mapItem* findItem(keyInt key, mapItem* node) {
    if (node != _map->rootNode) {
        if (key == node->key)
            return node;
        else if (key < node->key)
            return findItem(key, node->left);
            return findItem(key, node->right);
    } else return NULL;
}

从树的顶部开始,如果当前键大于搜索键,你只需向左递归,如果更小则向右递归。如果键相等,返回当前节点。如果到达树的底部仍未找到键,返回 NULL,因为键不在地图中。

以下是你可以使用这个 findItem() 函数的一种方式:

mapItem* ret = findItem(someKey, 
_map->rootNode->parent);
if (ret)
    printNode(ret);

只要 findItem() 不返回 NULL,这段代码就应该从 _map 打印一个节点。