2011-04-04 48 views
2

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

这是我写来实现这一代码:

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; 
} 

请协助。谢谢。

回答

3

这取决于你打算如何使用数据。如果你只是偶尔需要通过按键来访问数据,但一般只需要访问它的顺序被插入,你应该只将数据存储在一个std::vector

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

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

如果您需要经常访问的关键要素,但仍需要保持插入的顺序,你可以使用一个std::mapstd::vector来存放数据:当你插入一个元素data

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

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

+0

如果元素被频繁添加/然后取出它会很慢,除去从向量的关键,特别是如果它是某个地方开始,因为你需要将所有的下列键填写孔。 – stefanB 2011-04-04 04:27:59

+0

因此,为了不对几个地方进行修改,我需要使用一个向量?另外,如何HashMap?我相信它是无序的。我需要经常按键访问元素,所以我需要一张地图或类似的东西。感谢您的回复。 – Shankar 2011-04-04 04:28:10

+0

@stefanB:这不是一个理想的解决方案,但它是微创,这是OP的要求之一。 – 2011-04-04 04:32:06

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; 
} 
+0

'无序'不是一个严格的弱排序;我不认为这会结束。 – 2011-04-04 15:11:05

+0

感谢您的回复 – Shankar 2011-04-05 05:46:59