【问题标题】:Problem with C++ MapC++ 地图的问题
【发布时间】:2011-07-28 21:59:59
【问题描述】:

我在使用地图时遇到了一些问题。我正在开发一个应用程序,我正在设计一个数据库,我面临一个问题,我需要将表模式存储在主内存中。地图中的元素会自动排序(根据键),我需要按原样排序。我希望元素以用户输入它们的方式插入到地图中。有没有我可以使用的替代数据结构?另外,在不知道这个事实的情况下,我开发了整个应用程序。只有在测试期间我才能弄清楚这件事(我的错!)。所以,如果我改成完全不同的数据结构,那么代码中有几个地方需要修改。请让我知道是否有一种简单的方法可以消除此问题,或者至少我可以使用类似的数据结构,以便 Map 上的操作类似于新数据结构的操作。

这是我为实现此目的而编写的代码:

class Attribute {
public:
    string attributeName;
    string type; //char, int, etc
    int size; //4 for int and corresponding size for char
};


class Table {
public:
    string tableName;
    map<string, Attribute> attribute;
    string primaryKey;
    int recordSize;
    int totalSize;
    int records;
};


Attribute CatalogMemoryHandler::createAttribute(string attributeName, string type, int size) {

    Attribute attribute;
    attribute.attributeName = attributeName;
    attribute.type = type;
    attribute.size = size;

    return attribute;
}


Table CatalogMemoryHandler::createTable(string tableName, string primaryKey, int recordsSize, int totalSize, int records) {

    Table tableObj;
    tableObj.tableName = tableName;
    tableObj.primaryKey = primaryKey;
    tableObj.recordSize = recordsSize;
    tableObj.totalSize = totalSize;
    tableObj.records = records;

    return tableObj;
}

bool CatalogMemoryHandler::addNewTable( string tableName,
                                            string primaryKey,
                            int recordSize,
                            int totalSize,
                            int records,
                            vector<string> listOfAttributeNames,
                            vector<string> listOfAttributeTypes,
                            vector<int> listofAttributeSizes
                ) {

Table newTable = createTable(tableName, primaryKey, recordSize, totalSize, records);

    for(int i = 0; i < (int) listOfAttributeNames.size(); i++) {

        Attribute attribute = createAttribute(listOfAttributeNames[i], listOfAttributeTypes[i], listofAttributeSizes[i]);
        newTable.attribute.insert( make_pair( listOfAttributeNames[i], attribute ) );
    }

        cout << "\n";
    table[tableName] = newTable;

    return true;
}

请帮忙。谢谢。

【问题讨论】:

    标签: c++ algorithm sorting data-structures map


    【解决方案1】:

    也许你可以欺骗地图,你总是添加最大的元素,因此地图将它们放在最后。但请注意,这不是一个安全的代码。如果您从单点和单线程进行插入,请使用它。这是示例代码

    #include "stdafx.h"
    #include <map>
    #include <string>
    
    class unordered
        : public std::binary_function<std::string,std::string,bool>
    {
    public:
        bool operator()(const std::string& lhs,const std::string& rhs)
        {
            if (lhs == str(NULL))
                return false;
            else
                return true;
        }
    
    public:
        static const char* str(char* str_p)
        {
            static char* val_p = NULL;
            if (str_p != NULL)
                val_p = str_p;
            return val_p;           
        }
    
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        std::map<std::string,int,unordered> s_map;
    
        unordered::str("d");
        s_map.insert(std::make_pair("d",4));
        unordered::str("a");
        s_map.insert(std::make_pair("a",1));
        unordered::str("b");
        s_map.insert(std::make_pair("b",2));
    
        return 0;
    }
    

    【讨论】:

    • unordered 不是严格的弱排序;我认为这不会有好的结局。
    【解决方案2】:

    这取决于您打算如何使用这些数据。如果您只是偶尔需要按键访问数据,但通常只需要按照插入的顺序访问,您应该将数据存储在std::vector

    std::vector<std::pair<Key, Value> > data;
    

    只要您始终使用push_back 添加元素并且从不重新排序元素(例如使用std::sort),这些元素将保持您插入它们的顺序。您可以使用std::find 对序列执行线性搜索,以找到具有给定键的元素。

    如果您需要频繁按键访问元素但仍需要维护插入顺序,可以使用std::mapstd::vector 来包含数据:

    std::map<Key, Value> data;
    std::vector<Key> key_insertion_order;
    

    每当您将元素插入data 时,请将键添加到key_insertion_order 序列的末尾。每当您从data 中删除一个元素时,请从序列中删除该键。

    【讨论】:

    • 如果元素被频繁添加/删除,那么从向量中删除键会变慢,特别是如果它位于开头的某个地方,因为您需要移动以下所有键来填充孔。
    • 所以,为了不修改几个地方,我需要使用向量对吗?另外,HashMap 怎么样?我相信它是无序的。我需要经常按键访问元素,所以我需要一个地图或任何类似的东西。不过感谢您的回复。
    • @stefanB:这不是一个理想的解决方案,但它是微创的,这是 OP 的要求之一。
    • @Shankar: std::unordered_map(以及许多实现提供的非标准hash_map)不按排序顺序存储其元素,但它也不按插入顺序存储其元素。通过键 通过插入索引的高效访问无法通过单个标准库容器完成:您要么需要使用一对容器,要么需要找到第三方容器或编写自己的容器.
    • 感谢您的回复。但是,由于我已经做了很多工作,我想按照 Stefan 的解决方案来维护一个包含键排序的向量。我会在我的应用程序的第 2 版中想到更好的东西。非常感谢大家!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多