Проблема с C ++ Map - PullRequest
       11

Проблема с C ++ Map

2 голосов
/ 04 апреля 2011

У меня возникла проблема с картой. Я занимаюсь разработкой приложения, в котором я проектирую базу данных, и столкнулся с проблемой, когда мне нужно хранить схему таблиц в основной памяти. Элементы на карте сортируются автоматически (согласно ключу), и мне нужно, чтобы порядок был таким, какой он есть. Я хочу, чтобы элементы были вставлены в карту так, как пользователь вводит их. Есть ли альтернативная структура данных, которую я могу использовать? Также, не зная этого факта, я разработал все приложение. Только во время тестирования я смог разобраться в этом (мой плохой!). Итак, если я перехожу на совершенно другую структуру данных, то в коде есть несколько мест, которые нуждаются в модификации. Пожалуйста, дайте мне знать, если есть простой способ устранить эту проблему или, по крайней мере, подобную структуру данных, которую я могу использовать, чтобы операции на 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;
}

Пожалуйста, помогите. Спасибо.

Ответы [ 2 ]

3 голосов
/ 04 апреля 2011

Это зависит от того, как вы собираетесь использовать данные.Если вам нужно лишь время от времени получать доступ к данным по ключу, но, как правило, просто нужно обращаться к ним в том порядке, в котором они были вставлены, вам следует просто сохранить данные в формате std::vector:

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

.так как вы всегда добавляете элементы, используя push_back, и никогда не переупорядочиваете элементы (например, используя std::sort), элементы останутся в том порядке, в котором вы их вставили.Вы можете использовать std::find, чтобы выполнить линейный поиск по последовательности, чтобы найти элемент с заданным ключом.

Если вам необходимо часто обращаться к элементам по ключу, но при этом необходимо поддерживать порядок вставки, выможно использовать std::map и std::vector для хранения данных:

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

Каждый раз, когда вы вставляете элемент в data, добавляйте ключ в конец последовательности key_insertion_order.Всякий раз, когда вы удаляете элемент из data, удаляйте ключ из последовательности.

1 голос
/ 04 апреля 2011

Может быть, вы можете обмануть карту, добавив всегда самый большой элемент, поэтому карта ставит их в конце.Но будьте осторожны, что это не безопасный код.Используйте его, если вы делаете свои вставки из одной точки и одного потока.вот пример кода

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