Карта C ++ STL Я не хочу ее сортировать! - PullRequest
23 голосов
/ 15 февраля 2010

Это мой код

map<string,int> persons;

persons["B"] = 123;
persons["A"] = 321;


for(map<string,int>::iterator i = persons.begin();
    i!=persons.end();
    ++i)
{
    cout<< (*i).first << ":"<<(*i).second<<endl;
}

Ожидаемый результат:

  B:123
  A:321

Но на выходе получается:

  A:321
  B:123

Я хочу сохранить порядок, в котором ключи и значения были вставлены в map<string,int>.

Возможно ли это? Или я должен использовать какую-то другую структуру данных STL? Какой?

Ответы [ 18 ]

0 голосов
/ 18 февраля 2012

`` struct Compare: public binary_function { bool operator () (int a, int b) {return true;} }; * * Тысяча одна

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

0 голосов
/ 26 февраля 2010

Используйте карту вместе с вектором итераторов при вставке в карту. (Итераторы карты гарантированно не будут признаны недействительными)

В приведенном ниже коде я использую Set установить myset; vector :: iterator> vec;

void printNonDuplicates () { vector :: iterator> :: iterator vecIter; for (vecIter = vec.begin (); vecIter! = vec.end (); vecIter ++) { соиЬ << (* vecIter) -> c_str () <

void insertSet (string str) { pair :: iterator, bool> ret; ret = myset.insert (str); если (ret.second) vec.push_back (ret.first); }

0 голосов
/ 22 февраля 2010

Для того, чтобы делать то, что они делают, и работать эффективно, карты используют хеш-таблицы и сортировку. Следовательно, вы можете использовать карту, если хотите отказаться от памяти порядка вставки, чтобы получить удобство и производительность поиска по ключу.

Если вам нужен сохраненный порядок вставки, один из способов - создать новый тип, который связывает сохраняемое вами значение с порядком, в котором вы его храните (вам нужно написать код, чтобы отслеживать порядок) , Затем вы будете использовать карту строки для этого нового типа для хранения. Когда вы выполняете поиск с помощью ключа, вы также можете получить порядок вставки, а затем отсортировать значения на основе порядка вставки.

Еще одна вещь: если вы используете карту, учтите тот факт, что проверка, если люди ["C"] существуют (после того, как вы только вставили A и B), фактически вставит пару ключ-значение в ваш карта.

0 голосов
/ 16 февраля 2010

Карта - упорядоченная коллекция (вторым параметром в шаблоне является функтор порядка), как установлено.Если вы хотите выложить элементы в этих последовательностях как pushd, вы должны использовать deque, list или vector.

0 голосов
/ 15 февраля 2010

Да, контейнер с картой не для вас.
Как вы и просили, вам нужен следующий код:

   struct myClass {
      std::string stringValue;
      int         intValue;
      myClass( const std::string& sVal, const int& iVal ):
               stringValue( sVal ),
               intValue( iVal) {}
   };

   std::vector<myClass> persons;

   persons.push_back( myClass( "B", 123 ));
   persons.push_back( myClass( "A", 321 ));


   for(std::vector<myClass>::iterator i = persons.begin();
      i!=persons.end();
      ++i)
   {
      std::cout << (*i).stringValue << ":" << (*i).intValue << std::endl;
   }

Здесь выходные данные не отсортированы, как ожидалось.

0 голосов
/ 15 февраля 2010

Я также думаю, что Карта - это не тот путь. Ключи на карте образуют набор; один ключ может появиться только один раз. Во время вставки в карту карта должна искать ключ, чтобы убедиться, что он не существует, или чтобы обновить значение этого ключа. Для этого важно (с точки зрения производительности), чтобы ключи и, следовательно, записи имели своего рода порядок. Таким образом, карта с упорядочением вставок будет крайне неэффективна при вставках и извлечении записей.

Другая проблема может возникнуть, если вы дважды используете один и тот же ключ; должна быть сохранена первая или последняя запись и должна ли она обновлять порядок вставки или нет?

Поэтому я предлагаю вам воспользоваться предложением Neils, вектором для упорядочения по времени вставки и картой для поиска по ключу.

0 голосов
/ 23 сентября 2015

Существует std :: unordered_map , который вы можете проверить. С первого взгляда похоже, что это может решить вашу проблему.

0 голосов
/ 15 февраля 2010

я бы проголосовал за typedef std::vector< std::pair< std::string, int > > UnsortedMap;

Назначение выглядит немного по-другому, но ваш цикл остается таким же, как сейчас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...