C++ geek
3.56K subscribers
251 photos
2 videos
16 links
Учим C/C++ на примерах
Download Telegram
Алгоритм next_permutation

next_permutation(first, last) - переставляет элементы так, чтобы получилась следующая в лексикографическом порядке перестановка. Можно применять не только к векторам, но и к строкам (как и многие другие алгоритмы).

Метод возвращает true, если удалось построить следующую в лексикографическом порядке перестановку. Если же первоначальная перестановка уже была максимальной в лексикографическом порядке, то метод генерирует минимальную в лексикографическом порядке перестановку и возвращает false.
Бесконечный цикл

Для чего? Когда while(true), while(1), for(;;) и прочие стандартные пути создания цикла кажутся не слишком информативными, можно использовать подобный макрос. Единственный плюс который он дает — чуть лучшую читаемость кода.

➡️ @cpp_geek
Метод map::emplace_hint

Аналогичен методу emplace(), но дополнительно позволяет подсказать позицию вставки с помощью итератора. Метод возвращает итератор на вставленный элемент или на существующий элемент (вставить элемент с одинаковым ключом нельзя).

➡️ @cpp_geek
Что лучше const или define?

Ответ:
define - это директива препроцессора, которая не учитывает ни типов, ни областей видимости. Препроцессор вставляет значение везде, где оно используется и создается множество копий 3.14159265359 в объектном коде, константа никогда не порождает больше одной копии этого значения. define трудно отлаживать, потому что у него нет имени, только магическое число, нельзя взять адрес или создать ссылку на это значение.

У const есть тип, область видимости, можно взять адрес, создать константную ссылку на эту переменную.

Определенно, лучше использовать const, а не define.

➡️ @cpp_geek
Шаблон Voodoo

Вы можете настраивать шаблоны класса под конкретные значения или типы аргументов: так работает специализация шаблонов классов C++. Если это рекурсия, можно записывать базовые случаи, а затем определить общий шаблон как рекурсивную комбинацию этих случаев.

Больше интересного по ссылке.

➡️ @cpp_geek
this является const указателем

Указатель this является неизменяемым указателем. Убедимся это на примере:

class Foo {
private:
int x;
public:
Foo(int x = 0) { this->x = x; }
void change(Foo *foo) { this = foo; }
void print() { cout << x << endl; }
};

Здесь в методе change мы пытаемся присвоить указателю this новое значение.

Попробуем вызвать метод change в методе main:

Foo obj (3);
Foo *ptr;
obj.change(ptr);
obj.print();


Если мы запустим код, то получим ошибку компиляции в методе change (lvalue required as left operand of assignment). Компилятор не позволяет нам изменить значение указателя this.


➡️ @cpp_geek
Алгоритм unique_copy

std::unique используется для удаления дубликатов любого элемента, присутствующего последовательно в диапазоне [первый, последний). Он выполняет эту задачу для всех подгрупп, присутствующих в диапазоне, в котором последовательно присутствует один и тот же элемент.

Но что, если мы не хотим изменять исходный диапазон, а просто хотим, чтобы результат std::unique был скопирован в другой контейнер, для этого у нас есть другая функция std::unique_copy() . При этом копируется только первый элемент из каждой последовательной группы эквивалентных элементов в диапазоне [first, last).

➡️ @cpp_geek
Отличия между указателем и массивом?

Массивы создаются в статической памяти или в стеке. Указатели могут указывать на любой тип в памяти. В массивах можно изменять содержимое, а по указателю не всегда.

➡️ @cpp_geek
Функция resize

Изменяет размер контейнера так, чтобы он содержал n элементов.

Если n меньше текущего размера контейнера , содержимое сокращается до первых n элементов, удаляя все остальные (и уничтожая их).

Если n больше текущего размера контейнера , содержимое расширяется, вставляя в конце столько элементов, сколько необходимо для достижения размера n . Если указан val , новые элементы инициализируются как копии val , в противном случае они инициализируются значением.

Если n также больше, чем текущая вместимость контейнера, происходит автоматическое перераспределение выделенного пространства для хранения.

➡️ @cpp_geek
Функция for_each()

Функция принимает список в качестве входных данных и применяет пользовательскую функцию к каждому элементу этого списка. Это полезно, когда нам нужно выполнить одну и ту же операцию со всеми элементами списка.

Выше приведен пример, где мы используем функцию для удвоения всех чисел в массиве.

➡️ @cpp_geek
Возврат нескольких значений из функции

Вы можете написать функцию, которая будет возвращать два и более значений, с помощью std::tuple и std::tie.

➡️ @cpp_geek
Алгоритм is_sorted_until

Используется для определения первого несортированного элемента в диапазоне [first, last). Он возвращает итератор к первому несортированному элементу в диапазоне, поэтому все элементы между первым и возвращенным итератором сортируются.

Его также можно использовать для подсчета общего количества отсортированных элементов в диапазоне. Он определяется внутри файла заголовка. Если весь диапазон отсортирован, он вернет итератор, указывающий на последний.

➡️ @cpp_geek
Удаление указателя NULL

Удаление указателя NULL не приводит к каким-либо изменениям и ошибкам.

➡️ @cpp_geek
Проверяем, содержит ли строка только буквы в C++

Мы можем использовать регулярное выражение, чтобы проверить, содержит ли строка только буквы.
Начиная с C++11, мы можем использовать std::regex_match для сопоставления последовательности с регулярным выражением.

➡️ @cpp_geek
Токенизация строки

Токенизация строки означает разделение строки относительно некоторого разделителя (разделителей). Есть много способов этого добиться.

Рассмотрим пример с функцией strtok(). Она разбивает строку по указанным разделителям и должна быть вызвана в цикле, на каждой итерации возвращая следующую часть. В конце возвращает NULL

➡️ @cpp_geek
Сколько раз будет выполняться этот цикл?

Еще один вопрос с подвохом с IT-собеседований. Если бы вы сказали 300, а i был объявлен как int, вы были бы правы. Но поскольку i объявлен как unsigned char, правильный ответ – зацикливание (бесконечный цикл).

Объясняем. Выражение 2 * half_limit будет повышаться до int (на основе правил преобразования C++) и заимеет значение 300. Но так как i – это unsigned char, он пересматривается по 8-битному значению, которое после достижения 255 будет переполняться, поэтому вернется к 0, и цикл будет продолжаться вечно.

➡️ @cpp_geek
Алгоритм count_if

Алгоритм count_if выполняет подсчет количества выполнений условия в последовательности.

➡️ @cpp_geek
Макросы и функции

При первом знакомстве макросы могут показаться обычными вызовами функций. Конечно, у них немного странный синтаксис, но они «ведут себя» как обычные функции. Тогда в чём разница?

Макрос можно условно назвать функцией обработки и замены программного кода: после сборки программы макросы заменяются макроопределениями. На картинке показан код на Си.

➡️ @cpp_geek
Узнаем время работы программы на С++

Для того, чтобы найти время работы программы, нужно воспользоваться функцией clock(). Прототип функции clock() находится в заголовочном файле <ctime>, который нужно подключить.

Функция clock() возвращает значение времени в миллисекундах (1с = 1000млс). Причём отсчёт времени начинается с момента запуска программы.

➡️ @cpp_geek
Алгоритм adjacent_find

Ищет первую пару одинаковых соседних элементов в диапазоне, ограниченном итераторами [first, last). Если соседние дубликаты найдены, то алгоритм возвращает однонаправленный итератор, указывающий на первый элемент пары, в противном случае возвращается last.

➡️ @cpp_geek
Алгоритм rotate

Меняет местами элементы в диапазоне [first, last) таким образом, что элемент n_first становится первым в новом диапазоне, а n_first-1 — последним.

Параметры:
first, last - диапазон элементов для изменения их порядка.
n_first - элемент, который должен стать первым в новом диапазоне.

➡️ @cpp_geek