Если списки отсортированы (list содержит свой собственный метод sort, std::sort с list не работает) и требуется объединить их в один, сохранив их порядок, то вместо splice используйте merge. merge объединяет два списка в один, и если два элемента оказываются одинаковыми, то в конечную версию попадает элемент из lstOne. Как и в случае со splice, список, переданный в качестве аргумента, по окончании объединения очищается.

Также list содержит несколько удобных операций для удаления элементов. Представьте, что вам требуется удалить все вхождения какого-либо элемента. Все, что для этого требуется сделать, это вызвать remove, передав такой аргумент, который при сравнении с элементами list будет давать (*p == item) != false, где p — это итератор list. remove вызывается вот так.

strLst.remove("Harry");

В результате из strLst будут удалены все элементы, у которых el == "Harry". Если требуется удалить элементы, которые удовлетворяют какому-либо предикату, такому как больше какого-либо значения, используйте remove_if.

bool inline even(int n) {

 return(n % 2 == 0);

}

list intLst;

// Fill up intLst...

intLst.remove_if(even); // Удаляет все элементы, для которых even(*p)

                        // != false

Если предикаты более сложные, то попробуйте использовать какие-то из функторов из . Например, если требуется удалить элементы, которые больше определенного значения, используйте в remove_if объединение из greater (из ) и bind2nd.

intLst.remove_if(std::bind2nd(std::greater(), 2));

В результате этого из intLst будут удалены все значения, которые больше 2. Эта запись несколько необычна, но ничего сложного в ней нет. bind2nd принимает два аргумента — объект функции (назовем ее f) и значение (v) — и возвращает объект функции, который принимает один аргумент (arg) и вызывает f(arg, v). bind2nd — это простой способ делать подобные вещи без необходимости писать набор небольших функций.

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

Смотри также

Рецепт 6.1.

<p>6.6. Отображение строк на другие объекты</p>Проблема

Имеются объекты, которые требуется сохранить в памяти, и вы хотите хранить их по ключам типа string. Требуется иметь возможность быстро добавлять, удалять и получать элементы (с, как максимум, логарифмической сложностью).

Решение

Для отображения ключей (string) на значения (любой тип, который подчиняется семантике значений) используйте стандартный контейнер map, объявленный в . Пример 6.6 показывает, как это делается.

Пример 6.6. Создание отображения строк

#include

#include

#include

using namespace std;

int main() {

 map strMap;

 strMap["Monday"] = "Montag";

 strMap["Tuesday"] = "Dienstag";

 strMap["Wednesday"] = "Mittwoch";

 strMap["Thursday"] = "Donnerstag";

 strMap["Friday"] = "Freitag";

 strMap["Saturday"] = "Samstag";

 // strMap.insert(make_pair("Sunday", "Sonntag"));

 strMap.insert(pair("Sunday", "Sonntag"));

 for(map::iterator p = strMap.begin();

  p != strMap.end(); ++p) {

  cout << "English: " << p->first

   << German: " << p->second << endl;

 }

 cout << endl;

 strMap.erase(strMap.find("Tuesday"));

 for (map::iterator p = strMap.begin();

  p ! = strMap.end(); ++p) {

  cout << "English: " << p->first

   << ", German: " << p->second << endl;

 }

}

Обсуждение

map — это ассоциативный контейнер, который отображает ключи на значения, предоставляет логарифмическую сложность вставки и поиска и постоянную сложность удаления одного элемента. Обычно разработчики используют отображение для хранения объектов по их ключам типа string. Именно это делает пример 6.6. В этом случае отображаемый тип является строкой, но он может быть почти чем угодно.

Отображение объявляется вот так.

map

 typename Value,  // Тип значения

Перейти на страницу:

Похожие книги