- •Алгоритмы немодифицирующие последовательность Операции с каждым элементом (For each)
- •Поиск (Find)
- •Найти повторение (Аdjacent find)
- •Подсчет (Count)
- •Сравнение на равенство (Equal)
- •Отличие (Mismatch)
- •Поиск подпоследовательности (Search)
- •Алгоритмы модифицирующие последовательность Копировать (Copy)
- •Обменять (Swap)
- •Преобразовать (Transform)
- •Заменить (Replace)
- •Заполнить (Fill)
- •Породить (Generate)
- •Удалить (Remove)
- •Разделить (Partitions)
- •Убрать повторы (Unique)
- •Расположить в обратном порядке (Reverse)
В предыдущей работе были рассмотрены общие вопросы, касающиеся стандартных алгоритмов, а также алгоритмы сортировки и поиска. В этой работе будут рассмотрены две группы алгоритмов: немодифицирующие последовательность и модифицирующие последовательность.1
Алгоритмы немодифицирующие последовательность Операции с каждым элементом (For each)
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
Самый простой алгоритм стандартной библиотеки. for_eachприменяет функцию f2к каждому элементу последовательности, заданной парой итераторов [first, last), еслиfвозвращает значение то оно игнорируется. Алгоритм возвращает в качестве результатаf. Хотя в стандарте это не указано явно, но принято, чтоfне должна пытаться изменить значение элемента переданного ей в качестве параметра.
Перед применением следует посмотреть список стандартных алгоритмов в поисках более специализированного алгоритма.
Приведенная ниже программа использует for_eachдля вычисления среднего значения элементов последовательности:
#include <algorithm>
#include <vector>
#include <list>
#include <iostream>
using namespace std;
class average_counter
{
public:
average_counter():sum(0),count(0){}
void operator() (int val)
{
cout << val <<", ";
sum += val;
count++;
}
double get_average()
{
return static_cast<double>(sum)/static_cast<double>(count);
}
private:
int sum;
int count;
};
int main()
{
vector<int> vec;
int k;
for (k = 0; k < 10; k++)
vec.push_back(rand()%10);
// В данном случае используется тот факт, что for_eachвозвращает
// f, объект типаaverage_counter, от которого с помощью дополнительных
// методов можно получить среднее значение, рассчитанное на основе
// данных полученных при проходе по элементам последовательности
double average = (for_each(vec.begin(),
vec.end(),
average_counter())).get_average();
cout << "Average value is " << average << endl;
кeturn 0;
}
Поиск (Find)
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value);
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred);
findнаходит в последовательности первый элемент равный заданному и возвращает итератор указывающий на него.findиспользует для сравненияoperator== , аfind_ifпредикатpred. Или более формально,findвозвращает первый итератор i в диапазоне [first, last), для которого соблюдаются следующие соответствующие условия: *i == value (или pred (*i) == true в случае алгоритмаfind_if).
Если требуемый элемент не найдем возвращается last.
Следующий код находит в последовательности все элементы равные 1:
vector<int> VectorOfInt;
.. //заполнить вектор
// найдем все элементы равные 1
vector<int>::iterator iter = VectorOfInt.begin();
while (1)
{
// найдем следующую единицу
iter = find(iter,VectorOfInt.end(),1);
//проверим результаты поиска
if (iter == VectorOfInt.end())
break;
.. // iterуказывает на следующий элемент равный 1
// передвинем итератор, чтобы начать новый поиска с элемента
//следующего за найденным
++iter;
}