Если списки отсортированы (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
// Fill up intLst...
intLst.remove_if(even); // Удаляет все элементы, для которых even(*p)
// != false
Если предикаты более сложные, то попробуйте использовать какие-то из функторов из . Например, если требуется удалить элементы, которые больше определенного значения, используйте в remove_if объединение из greater (из ) и bind2nd.
intLst.remove_if(std::bind2nd(std::greater
В результате этого из intLst будут удалены все значения, которые больше 2. Эта запись несколько необычна, но ничего сложного в ней нет. bind2nd принимает два аргумента — объект функции (назовем ее f) и значение (v) — и возвращает объект функции, который принимает один аргумент (arg) и вызывает f(arg, v). bind2nd — это простой способ делать подобные вещи без необходимости писать набор небольших функций.
list — это хорошая альтернатива вектору, когда требуется стандартный последовательный контейнер. Другое внутреннее представление list позволяет ему обеспечить другой уровень сложности многих стандартных операций с последовательностями и несколько дополнительных операций.
Рецепт 6.1.
6.6. Отображение строк на другие объекты
Имеются объекты, которые требуется сохранить в памяти, и вы хотите хранить их по ключам типа string. Требуется иметь возможность быстро добавлять, удалять и получать элементы (с, как максимум, логарифмической сложностью).
Для отображения ключей (string) на значения (любой тип, который подчиняется семантике значений) используйте стандартный контейнер map, объявленный в . Пример 6.6 показывает, как это делается.
#include
#include
#include
using namespace std;
int main() {
map
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
for(map
p != strMap.end(); ++p) {
cout << "English: " << p->first
<< German: " << p->second << endl;
}
cout << endl;
strMap.erase(strMap.find("Tuesday"));
for (map
p ! = strMap.end(); ++p) {
cout << "English: " << p->first
<< ", German: " << p->second << endl;
}
}
map — это ассоциативный контейнер, который отображает ключи на значения, предоставляет логарифмическую сложность вставки и поиска и постоянную сложность удаления одного элемента. Обычно разработчики используют отображение для хранения объектов по их ключам типа string. Именно это делает пример 6.6. В этом случае отображаемый тип является строкой, но он может быть почти чем угодно.
Отображение объявляется вот так.
map
typename Value, // Тип значения