Сравниваем два списка файлов на C++!
Допустим, есть ожидаемый список файлов релиза и список того, что реально попало в папку. Нужно быстро понять, какие файлы отсутствуют, не проходя вручную по каждому имени.
Для этого удобно использовать std::ranges::set_difference. Алгоритм работает с отсортированными диапазонами и сразу возвращает элементы, которые есть в первом списке, но отсутствуют во втором.
Сначала приводим оба списка к одному порядку. Это важно, потому что set_difference не сортирует данные самостоятельно.
Теперь создаём контейнер для результата и передаём в него элементы, которые не нашлись во втором диапазоне.
В missing останется только config. Так же можно искать лишние файлы, поменяв expected и actual местами.
Этот приём подходит для проверки состава релиза, конфигураций, прав доступа и любых двух наборов строк. Главное помнить про сортировку и не хранить дубликаты там, где они не имеют смысла.
📣 C++ Ready | #практика
Допустим, есть ожидаемый список файлов релиза и список того, что реально попало в папку. Нужно быстро понять, какие файлы отсутствуют, не проходя вручную по каждому имени.
Для этого удобно использовать std::ranges::set_difference. Алгоритм работает с отсортированными диапазонами и сразу возвращает элементы, которые есть в первом списке, но отсутствуют во втором.
std::vector<std::string> expected = {"app", "config", "readme"};
std::vector<std::string> actual = {"app", "readme"};Сначала приводим оба списка к одному порядку. Это важно, потому что set_difference не сортирует данные самостоятельно.
std::ranges::sort(expected);
std::ranges::sort(actual);
Теперь создаём контейнер для результата и передаём в него элементы, которые не нашлись во втором диапазоне.
std::vector<std::string> missing;
std::ranges::set_difference(expected, actual,
std::back_inserter(missing));
В missing останется только config. Так же можно искать лишние файлы, поменяв expected и actual местами.
for (const auto& name : missing) {
std::cout << "Missing: " << name << '\n';
}Этот приём подходит для проверки состава релиза, конфигураций, прав доступа и любых двух наборов строк. Главное помнить про сортировку и не хранить дубликаты там, где они не имеют смысла.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍5🔥2
Считаем медиану потока чисел на C++!
Представьте, что значения приходят постоянно, а медиану нужно знать после каждого нового числа. Полная сортировка на каждом шаге будет лишней.
В этой задаче:
Решение подходит для поступающих в реальном времени измерений, цен и задержек.
📣 C++ Ready | #задача
Представьте, что значения приходят постоянно, а медиану нужно знать после каждого нового числа. Полная сортировка на каждом шаге будет лишней.
В этой задаче:
• делим числа на две кучи
• поддерживаем размеры половин
• берём медиану из верхушек куч
Решение подходит для поступающих в реальном времени измерений, цен и задержек.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥7👍5😁1
Визуализируем сортировку с SFML и C++20!
QuickSort проще понять, когда видно, как массив делится на части и элементы меняются местами. Автор берёт случайные числа, рисует их столбцами в окне SFML и связывает сортировку с обновлением изображения.
В статье разбирают:
• как подготовить массив и окно для визуализации
• как работает разбиение вокруг опорного элемента
• где рекурсия сортирует левую и правую части
📣 C++ Ready | #статья
QuickSort проще понять, когда видно, как массив делится на части и элементы меняются местами. Автор берёт случайные числа, рисует их столбцами в окне SFML и связывает сортировку с обновлением изображения.
В статье разбирают:
• как подготовить массив и окно для визуализации
• как работает разбиение вокруг опорного элемента
• где рекурсия сортирует левую и правую части
Продолжай читать на Habr
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤6👎2🔥2
Шпаргалка по ассоциативным контейнерам C++!
На картинке сравниваются set, map, unordered_set и unordered_map. Схемы показывают, где хранятся только ключи, где пары ключ-значение и чем упорядоченное дерево отличается от хеш-таблицы.
Например, map подходит, когда нужно обходить ключи по порядку, а unordered_map удобен для поиска без требования к порядку. Рядом есть короткие примеры вставки и доступа к элементам.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
На картинке сравниваются set, map, unordered_set и unordered_map. Схемы показывают, где хранятся только ключи, где пары ключ-значение и чем упорядоченное дерево отличается от хеш-таблицы.
Например, map подходит, когда нужно обходить ключи по порядку, а unordered_map удобен для поиска без требования к порядку. Рядом есть короткие примеры вставки и доступа к элементам.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍5🔥3
Ищем команды по префиксу на C++!
В CLI-приложении пользователь может помнить только начало команды. Сделаем поиск подсказок, который быстро находит подходящие варианты в отсортированном списке.
В этой задаче:
Такой подход пригодится для автодополнения команд и названий настроек.
📣 C++ Ready | #задача
В CLI-приложении пользователь может помнить только начало команды. Сделаем поиск подсказок, который быстро находит подходящие варианты в отсортированном списке.
В этой задаче:
• сортируем команды
• находим начало через lower_bound
• собираем слова с нужным префиксом
Такой подход пригодится для автодополнения команд и названий настроек.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥5👍3
Как оплачивать зарубежные сервисы в 2026 году?
Можно бегать между посредниками и бояться блокировок после оплаты, а можно выпустить международную карту Lumio Pay и пользоваться любимыми сервисами без рисков.
— выпуск карты за 2 минуты
— лучший курс пополнения на рынке (у конкурентов на 20% выше)
— пополнение рублями или криптой
— чистые BIN карт, оплата без риска блокировок
Пока все ищут идеальное решение, оно у тебя перед глазами: @LumioPay
Можно бегать между посредниками и бояться блокировок после оплаты, а можно выпустить международную карту Lumio Pay и пользоваться любимыми сервисами без рисков.
— выпуск карты за 2 минуты
— лучший курс пополнения на рынке (у конкурентов на 20% выше)
— пополнение рублями или криптой
— чистые BIN карт, оплата без риска блокировок
Пока все ищут идеальное решение, оно у тебя перед глазами: @LumioPay
👎3❤1👍1
Знали, почему пути к файлам в C++ лучше собирать через std::filesystem::path?
Код может быстро обрастать ручными слешами, проверками расширения и поиском последнего разделителя:
Это может работать, но чем больше операций с путём, тем сложнее поддерживать строковые трюки. std::filesystem::path даёт для таких операций отдельный тип:
Оператор / соединяет части пути с учётом формата текущей платформы. Не приходится решать, какой разделитель вставлять между папками.
Части готового пути тоже можно получать без поиска символов:
Это удобно, например, когда нужно оставить только имя файла для лога или проверить расширение перед обработкой. Все три результата остаются объектами path, поэтому при выводе или передаче строковому API учитывайте требуемую кодировку.
Если в пути есть лишние точки или переходы в соседнюю папку, можно привести его к нормальной лексической форме:
Здесь получится путь data/report.txt. Но lexically_normal не обращается к файловой системе и не проверяет, существует ли файл. Это преобразование записи пути, а не проверка безопасности.
Есть и важная ловушка. Если правая часть уже является абсолютным путём, она может заменить основу:
Поэтому пользовательский путь нельзя без проверки присоединять к базовой папке, если важно остаться внутри неё. Для обычного построения путей path убирает много ручной работы.
📣 C++ Ready | #совет
Код может быстро обрастать ручными слешами, проверками расширения и поиском последнего разделителя:
std::string file = base + "/logs/app.log";
Это может работать, но чем больше операций с путём, тем сложнее поддерживать строковые трюки. std::filesystem::path даёт для таких операций отдельный тип:
namespace fs = std::filesystem;
fs::path file = fs::path(base) / "logs" / "app.log";
Оператор / соединяет части пути с учётом формата текущей платформы. Не приходится решать, какой разделитель вставлять между папками.
Части готового пути тоже можно получать без поиска символов:
auto name = file.filename();
auto folder = file.parent_path();
auto extension = file.extension();
Это удобно, например, когда нужно оставить только имя файла для лога или проверить расширение перед обработкой. Все три результата остаются объектами path, поэтому при выводе или передаче строковому API учитывайте требуемую кодировку.
Если в пути есть лишние точки или переходы в соседнюю папку, можно привести его к нормальной лексической форме:
fs::path clean = (fs::path("data") / "temp" / ".." / "report.txt")
.lexically_normal();Здесь получится путь data/report.txt. Но lexically_normal не обращается к файловой системе и не проверяет, существует ли файл. Это преобразование записи пути, а не проверка безопасности.
Есть и важная ловушка. Если правая часть уже является абсолютным путём, она может заменить основу:
fs::path result = fs::path("/srv/app") / "/tmp/log.txt";Поэтому пользовательский путь нельзя без проверки присоединять к базовой папке, если важно остаться внутри неё. Для обычного построения путей path убирает много ручной работы.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍4🔥4
Можно ли собирать обычные C++-приложения в браузере?
Автор описывает систему, где прямо в браузере работает набор инструментов для сборки нативных приложений под разные платформы.
В статье разбирают:
• зачем понадобился единый слой над платформенными библиотеками
• как clang и lld удалось запустить через WebAssembly
• чем заменили привычные вызовы fork и внешних утилит
• как из браузера собирается и запускается приложение с графикой
Это история о реальных ограничениях кроссплатформенной сборки и о том.
📣 C++ Ready | #статья
Автор описывает систему, где прямо в браузере работает набор инструментов для сборки нативных приложений под разные платформы.
В статье разбирают:
• зачем понадобился единый слой над платформенными библиотеками
• как clang и lld удалось запустить через WebAssembly
• чем заменили привычные вызовы fork и внешних утилит
• как из браузера собирается и запускается приложение с графикой
Это история о реальных ограничениях кроссплатформенной сборки и о том.
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍3🔥3👎2
⚡️ Полный стек специалиста по кибербезопасности в одном бандле
Хватит собирать знания по крупицам. Мы объединили 5 флагманских прикладных курсов CyberYozh Academy в единую экосистему.
Все ключевые инструменты для работы в безопасности и автоматизации:
▪️ Базы данных: SQL для хакера
▪️ ОС и инфраструктура: Linux CyberPunk (с официальным дипломом сисадмина)
▪️ Практический пентест: HackerPoint + HackerPoint (Blue vs Red Team)
▪️ Кодинг и автоматизация: AI-помощники на Python
Вместо покупки разрозненных курсов по отдельности(~250 000 ₽), вы забираете полный комплект за 50 000 ₽.
⚠️В открытом доступе на сайте этого бандла нет - предложение доступно только по прямому запросу.
🦔 Отправь промокод
👉@cyacademy_support
Хватит собирать знания по крупицам. Мы объединили 5 флагманских прикладных курсов CyberYozh Academy в единую экосистему.
Все ключевые инструменты для работы в безопасности и автоматизации:
▪️ Базы данных: SQL для хакера
▪️ ОС и инфраструктура: Linux CyberPunk (с официальным дипломом сисадмина)
▪️ Практический пентест: HackerPoint + HackerPoint (Blue vs Red Team)
▪️ Кодинг и автоматизация: AI-помощники на Python
Вместо покупки разрозненных курсов по отдельности
⚠️В открытом доступе на сайте этого бандла нет - предложение доступно только по прямому запросу.
CReady в чат с менеджером, чтобы закрепить за собой скидку и узнать подробности: 👉@cyacademy_support
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5😁1
Почему unique_ptr::release() может оставить объект в памяти навсегда?
Обычно unique_ptr удаляет объект, когда владелец выходит из области видимости. Это одна из причин, почему его удобно возвращать из функций и хранить в классе:
Но у unique_ptr есть метод release. Название звучит так, будто он освобождает память:
На самом деле release освобождает unique_ptr от владения объектом. Он возвращает обычный указатель и оставляет ответственность за удаление вызывающему коду. Если результат проигнорировать, объект больше никто не удалит.
Когда нужен только временный доступ без передачи владения, используйте get:
ptr по-прежнему владеет объектом. Сохранить borrowed после уничтожения ptr нельзя, зато вручную удалять его тоже не нужно.
Если объект нужно уничтожить прямо сейчас, подойдет reset:
После reset указатель станет пустым, а объект будет удалён через deleter, который хранит unique_ptr. Это не то же самое, что release.
Когда другая функция принимает unique_ptr, передайте владение явно:
get берёт указатель на время, reset удаляет объект, release отдаёт ответственность вам.
📣 C++ Ready | #совет
Обычно unique_ptr удаляет объект, когда владелец выходит из области видимости. Это одна из причин, почему его удобно возвращать из функций и хранить в классе:
auto ptr = std::make_unique<Widget>();
Но у unique_ptr есть метод release. Название звучит так, будто он освобождает память:
ptr.release();
На самом деле release освобождает unique_ptr от владения объектом. Он возвращает обычный указатель и оставляет ответственность за удаление вызывающему коду. Если результат проигнорировать, объект больше никто не удалит.
Когда нужен только временный доступ без передачи владения, используйте get:
Widget* borrowed = ptr.get();
use(*borrowed);
ptr по-прежнему владеет объектом. Сохранить borrowed после уничтожения ptr нельзя, зато вручную удалять его тоже не нужно.
Если объект нужно уничтожить прямо сейчас, подойдет reset:
ptr.reset();
После reset указатель станет пустым, а объект будет удалён через deleter, который хранит unique_ptr. Это не то же самое, что release.
Когда другая функция принимает unique_ptr, передайте владение явно:
consume(std::move(ptr));
get берёт указатель на время, reset удаляет объект, release отдаёт ответственность вам.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🔥2