Problem with C++ Map
I am facing some problem with Map. I am developing an application where I am designing a database and I am facing a problem where I need to store table schema in Main Memory. The elements in the map are getting sorted automatically (as per the key) and I need the ordering to be as it is. I want the elements to be inserted in the Map as the way the user enters them. Is there an alternative data structure that I can use? Also, without knowing this fact, I have developed the entire application. Only during testing I could figure out this thing (My bad!). So, if I change to a completely different data structure, then there are several places in the code that needs modification. Please let me know if there is a simple way to eliminate this problem, or at least a similar data structure which I can use so that the operations on Map are similar to that of the new data structure.
This is the code I have written to achieve this:
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;
table开发者_StackOverflow中文版Obj.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;
}
Please assist. Thank you.
It depends on how you intend to use the data. If you only occasionally need to access the data by key but generally just need to access it in the order in which it is inserted, you should just store the data in a std::vector
:
std::vector<std::pair<Key, Value> > data;
As long as you always add elements using push_back
and never reorder the elements (e.g. using std::sort
), the elements will remain in the order in which you inserted them. You can use the std::find
to perform a linear search over the sequence to find the element with a given key.
If you need to frequently access elements by key but still need to maintain the order of insertion, you can use a std::map
and a std::vector
to contain the data:
std::map<Key, Value> data;
std::vector<Key> key_insertion_order;
Whenever you insert an element into data
, add the key to the end of the key_insertion_order
sequence. Whenever you remove an element from data
, remove the key from the sequence.
Maybe you can trick the map that, you add always the biggest elementh therefore map puts them at the end. But be carefull that this is not a safe code. Use it, if you make your insertions from a single point and single thread. here is the sample code
#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;
}
精彩评论