eraseи remove(и связанные с ними алгоритмы) предлагают удобный способ удалять определенные элементы последовательностей. Они предоставляют простую альтернативу самостоятельному перебору и поиску нужных элементов с последующим их удалением по одному.
Смотри также
Рецепты 6.2 и 7.1.
7.3. Случайное перемешивание данных
Проблема
Имеется последовательность данных и требуется перемешать их так, чтобы они были расположены в случайном порядке.
Решение
Используйте стандартный алгоритм random_shuffle, определенный в . random_shuffleпринимает два итератора произвольного доступа и (необязательно) функтор генератора случайных чисел и реорганизует случайным образом элементы заданного диапазона. Пример 7.3 показывает, как это делается.
Пример 7.3. Случайное перемешивание последовательностей
#include
#include
#include
#include
#include "utils.h" // Для printContainer(): см. 7.10
using namespace std;
int main() {
vector v;
back_insert_iterator > p = back_inserter(v);
for (int i = 0; i < 10; ++i) *p = i;
printContainer(v, true);
random_shuffle(v.begin(), v.end());
printContainer(v, true);
}
Вывод должен выглядеть примерно так.
-----
0123456789
-----
8192057346
Обсуждение
random_shuffleочень прост в использовании. Дайте ему диапазон, и он перемешает этот диапазон случайным образом. Имеется две версии, и их прототипы выглядят так.
void random_shuffle(RndIter first, RndIter last);
void random_shuffle(RndIter first, RndIter last, RandFunc& rand);
В первой версии используется зависящая от реализации функция генерации случайных чисел, которой должно быть достаточно для большинства задач. Если ее недостаточно — например, требуется неоднородное распределение, такое, как гауссово — то можно написать собственную функцию, которую можно передать во вторую версию.
Этот генератор случайных чисел должен быть функтором с единственным аргументом, возвращающим единственное значение, и оба они должны преобразовываться в iterator_traits::difference_type. В большинстве случаев для этого подойдет целое число. Например, вот мой псевдогенератор случайных чисел.
struct RanNumGenFtor {
size_t operator()(size_t n) const {
return(rand() % n);
}
} rnd;
random_shuffle(v.begin(), vend(), rnd);
Приложения random_shuffleограничены последовательностями, которые предоставляют итераторы случайного доступа ( string, vectorи deque), массивами или собственными контейнерами, удовлетворяющими этому требованию. Перемешать случайным образом ассоциативный контейнер невозможно, так как его содержимое всегда хранится в упорядоченном виде. На самом деле для ассоциативных контейнеров не всегда можно использовать алгоритм, изменяющий его диапазон (и который часто называется видоизменяющим ( mutating ) алгоритмом).
7.4. Сравнение диапазонов
Проблема
Имеется два диапазона и требуется сравнить их на равенство или определить, какой из них меньше, чем другой, основываясь на каком-либо порядке сортировки элементов.
Решение
В зависимости от типа выполняемого сравнения используйте один из стандартных алгоритмов — equal, lexicographical_compareили mismatch, определенных в . Пример 7.4 показывает некоторые из них в действии.
Пример 7.4. Различные типы сравнения
#include
#include
#include
#include
#include "utils.h"
using namespace std;
using namespace utils;
int main() {
vector vec1, vec2;
vec1.push_back("Charles");
vec1.push_back("in");
vec1.push_back("Charge");
vec2.push_back("Charles");
vec2.push_back("in");
vec2.push_back("charge"); // Обратите внимание на строчную "с"
if (equal(vec1.begin(), vec1.end(), vec2.begin())) {
cout << "Два диапазона равны!" << endl;
} else {
cout << "Два диапазона HE равны!" << endl;
}
string s1 = "abcde";
string s2 = "abcdf";
string s3 = "abc";
cout << boolalpha // Отображает логические значения как "true" или "false"
<< lexicographical_compare(s1.begin(), s1.end(),
s1.begin(), s1.end()) << endl;
cout << lexicographical_compare(s1.begin(), s1.end(),
s2.begin(), s2.end()) << endl;
cout << lexicographical_compare(s2.begin(), s2.end(),
s1.begin(), s1.end()) << endl;
cout << lexicographical_compare(s1.begin(), s1.end(),
s3.begin(), s3.end()) << endl;
cout << lexicographical_compare(s3.begin(), s3.end(),
s1.begin(), s1.end()) << endl;
pair iters =
Читать дальше