Непонятное поведение вставки std :: map - PullRequest
3 голосов
/ 10 июля 2010

Я получаю странное поведение при вставке значений в карту: я всегда вставляю в конец карты, но иногда записи выходят из строя.

Если я проведу прямой тест, то у меня не возникнет проблем - номера правильно упорядочены:

map<int,int> testMap;
for(int i = 0; i < 100; ++i)
{
    // everything is ordered correctly here
    testMap.insert(testMap.end(), pair<int,int>(i,i));
}

Но когда я анализирую строку и пытаюсь вставить значения в том же порядке, в каком я их читал, то все получается не так хорошо:

const string INPUT_TWO =
"=VAR STRING1 \"MYSTRING\"\n\
=VAR STRING2 \"EXAMPLE\"\n\
=VAR NUMBER1 12345\n\
=VAR NUMBER2 23456\n\
=VAR DUMMY 1111\n";

const string VAL_STRING = "VAR";

vector<pair<string, string>> parse_fields(const string & input)
{
    map<string, string> fieldsMap;
    vector<pair<string, string>> sequenceFields;
    vector<string> lines = split(input, '\n');
    for(size_t i = 0; i < lines.size(); ++i)
    {
        if(lines[i].find(VAL_STRING)!=string::npos)
        {
            vector<string> vals = split(lines[i], ' ');
            if(vals.size()==3)
            {
                fieldsMap.insert(fieldsMap.end(), pair<string,string>(vals[1], remove_quotes(vals[2])));
                sequenceFields.push_back(pair<string,string>(vals[1], remove_quotes(vals[2])));
            }
        }
    }

    // at the end the map looks like:
    // "DUMMY", "1111"
    // "NUMBER1", "12345"
    // "NUMBER2", "23456"
    // "STRING1", "MYSTRING"
    // "STRING2", "EXAMPLE"

    // the vector of pairs looks like:
    // "STRING1", "MYSTRING"
    // "STRING2", "EXAMPLE"
    // "NUMBER1", "12345"
    // "NUMBER2", "23456"
    // "DUMMY", "1111"

    return sequenceFields;
}

Для справки, я вставил весь дополнительный код в pastie .

Кто-нибудь знает, почему это может происходить?

Ответы [ 2 ]

4 голосов
/ 10 июля 2010

A std::map - это заказанный контейнер, это то, что позволяет ему проводить поиск. Если вам нужны как отображение, так и листинг, рассмотрите возможность использования Boost.MultiIndex .

1 голос
/ 10 июля 2010

Карты изначально не упорядочены.Концептуально они представляют пары ключ-значение.Но C ++ std::map карты внутренне упорядочены.См. http://www.cplusplus.com/reference/stl/map/.Таким образом, записи будут эффективно отсортированы по ключевым значениям.

Если вам нужен ваш собственный порядок, вы должны использовать список кортежей.Или unordered_map, если он у вас есть (см. http://en.wikipedia.org/wiki/Unordered_map_%28C%2B%2B%29; hash_map, вероятно, доступно на вашей платформе).Или сортируйте результаты по мере их получения.

...