неділю, 15 березня 2009 р.

Класифікація алгоритмів STL

Класифікація алгоритмів:

Cуфікс _if - використовується при наявності двох схожих форм алгоритму з однаковою кількітю параметрів. Версія без суфіксу використовується при передачі значення, аверсія з суфіксом _if при передачі функції, або об'єкту функції. Якщо ж версія алгоритму відрізняється додатковим параметром - вона зберігає за собою попереднє ім'я, тобто вживається без суфіксу.

Cуфікс _сopy означає, що алгоритм не тільки обробляє елементи, а й копіює їх в інтервал, який приймає. Наприклав reverse() переставляє елементи в зворотньому порядку, а reverse_sopy() копіює елементи в інтервал в зворотньому напрямку.

Алгоритми поділяються на групи:

  • не модифікуючі: for_each, count, max/min_element, search, find
  • модифікуючі: for_each, copy, merge, fill, replace
  • алгоритми видалення: remove, remove_if, remove_copy_if, unique
  • алгоритми перестановки: reverse, rotate, random_shuffle, partition, stable_partition
  • алгоритми сортування: sort, stable_sort, partial_sort, partition, stable_partition, make_heap, push/pop_heap, sort_heap
  • алгоритми впорядкованих інтервалів: binary_search, lower/upper_bound, equal_range, merge, set_difference
  • числові алгоритми: accumulate, inner_product, adjacent_difference, partial_sum

Детальний опис алгоритмів можна знайти в книзі Nicolai M.Josuttis The C++ Standard, Chapter 9 Algorithms STL.

вівторок, 3 березня 2009 р.

Оператори ->* , .*

Якось я захотів створити вказівник на функцію класу, і в залежності від певних обставин присвоювати йому вказівники на інші функції цього ж класу, для того, щоб при звернені до цього вказівника викликалась потрібна мені (залежно від обставин) функція. Звісно ж без знання цих операторів у мене нічого не вийшло. Дивно, що у багатьох авторитетних книжках по C++ про це не написано. Хочу звернути увагу, що ->* це не два окремих оператори, а один, так само як і .* Стрілочка-зірочка та крапочка-зірочка - окремі визначені оператори C++.

Ось простенький приклад:



#include < iostream>
using namespace std;
class MyClass
{
public:
MyClass(){}
~MyClass(){}

typedef void (MyClass:: *MY_FUNC_PTR)(int val);
// екземпляр вказівника на функцію класу
MY_FUNC_PTR stateFuncPtr;

void stateWaitFunc(int val)
{
cout < < val < < ". State WAITING function()" < < endl;
}
void stateDoFunc(int val)
{
cout < < val < < ". State DOING function()" < < endl;
}
void someFunk()
{
// присвоюємо вказівник на stateDoFunc функцію
stateFuncPtr = &MyClass::stateDoFunc;
// виклик функції stateDoFunc шляхом звертання до нашого вказівника
(this->*stateFuncPtr)(1);
// присвоюємо вказівник на stateWaitFunc функцію
stateFuncPtr = &MyClass::stateWaitFunc;
// виклик функції stateWaitFunc шляхом звертання до вказівника
(this->*stateFuncPtr)(2);
}
};

int main()
{
MyClass m;
m.someFunk();
// присвоюємо вказівник на stateDoFunc функцію (зовні класу)
m.stateFuncPtr = &MyClass::stateDoFunc;
// виклик функції stateDoFunc шляхом звертання до вказівника
(m.*m.stateFuncPtr)(3);
return 0;
}

Матеріал взято з власного наступання на граблі.

Узагальнення ітераторів

Категорії ітераторів:

Категорія - Можливості - Підтримка

Ітератор вводу - читання в прямому напрямку - Потоковий Ітератор вводу.

Ітератор виводу - Запис в прямому напрямку - Потоковий Ітератор виводу, ітератор вставки.

Прямий ітератор  - Читання і запис в прямому напрямку

Двонаправлений ітератор - Читання і запис в оберненому напрямках -list, map, mulimap, set, multiset.

Ітератордовільного доступу - Читання і запис з довільним доступом - vector, deque, string, array

Ітераторні адаптери:

Обернені ітератори - адаптери, що перевизначають оператори ++ та -- так щоб пошук виконувався в оберненому порядку.

Ітератори вставки - адаптер, що перетворює присвоєння нового значення у вставку нового значення. Бувають: Кінцеві (додає нове значення в кінець контейнера викликом функції push_back()), Початкові (вставляє нове значення в початок контейнера викликом функції push_front()), Загальні (на основі функції insert()).

Потокові ітератори - адаптер, що використовує поток в якості джерела або приймача алгоритму. Потокові ітератопи виводу записують значення що присвоюється у вихідний потік даних. Потокові ітератопи вводу читають елементи з вхідного потоку даних.

Цікавий приклад потокових ітераторів:

Програма читає слова із стандартного потоку вводу і виводить їх у відсортованому порядку виключаючи дублікати.



#include < iostream>
#include < vector>
#include < string>
#include < algorithm>

using namespace std;

int main()
{
vector < string> coll;

// читання слів з вхідного потоку даних
copy (istream_iterator < string> (cin), // початок джерела
istream_iterator < string> (), // кінець джерела
back_inserter(coll)); // приймач

sort (coll.begin(), coll.end());

unique_copy(coll.begin(), coll.end(), // джерело
ostream_iterator < string> (cout, "\n"));// приймач
}


Матеріал взято із книги Nicolai M.Josuttis The C++ Standard Library

Прихильники