From 2a84bb538dbb94675b1c359578389ff194b404f1 Mon Sep 17 00:00:00 2001 From: Wammero <107371364+Wammero@users.noreply.github.com> Date: Sun, 28 Apr 2024 01:00:29 +0300 Subject: [PATCH 1/3] Update README.md --- README.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db5a50b4..db6aac87 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,47 @@ 4. Найденная в соответствии с условием задачи категория должна выводиться в изначальном наименовании, приведенном в файле с входными данными. Если таких категорий несколько, то на вывод они все подаются в алфавитном порядке. ## Автор решения - +Мусаев Нажмудин Леонардович +почта - nazhmud1@yandex.ru +telegram - @wammero ## Описание реализации +Этот код представляет собой программу на языке C++, которая анализирует данные о покупках, представленные в формате JSON, и определяет самые популярные категории товаров за определённый период времени. + +1)Структуры данных: +- item: Эта структура представляет купленный товар. Включает в себя идентификатор, название и категорию товара. +- category_class: Вложенная в item структура, представляющая категорию товара. Включает в себя идентификатор и название категории. +- date_time: Структура для хранения даты и времени покупки. +- bought: Структура, хранящая информацию о времени покупки и списке купленных товаров. + +2)Функции: +- set_time: Разбивает строку времени на составляющие (год, месяц, день, час, минута, секунда) и возвращает объект date_time. +- find: Основная функция для поиска самых популярных категорий товаров за определённый период времени. Принимает вектор всех покупок и два объекта date_time, представляющие начальную и конечную даты. Использует бинарный поиск для определения соответствующих покупок и подсчёта популярности категорий. +- print: Выводит результат в формате JSON. + +3)Основная логика: +- В функции main открывается файл JSON с данными о покупках и считывается в объект objJson. +- Данные о покупках извлекаются из объекта objJson и используются для создания экземпляров структуры bought. +- Экземпляры bought добавляются в вектор all_boughts. +- all_boughts сортируется по времени покупки для последующего бинарного поиска. +- Задаются начальная и конечная даты для анализа. +- Вызывается функция find, которая определяет популярные категории за заданный период времени. +- Результат выводится с помощью функции print. + +4)Примечания: +- В коде закомментированы строки, отвечающие за запись результата в файл JSON. Если требуется сохранение результата, эти строки можно использовать, раскомментировав их. +- Код написан с использованием стандартной библиотеки C++ и библиотеки nlohmann/json для работы с JSON данными + ## Инструкция по сборке и запуску решения +Задание было сделано в Visual Studio 2022 + +1)Для начала нужно скачать библиотеку для работы с json. (https://github.com/nlohmann/json/releases) + +2)Создать пустой проект и добавить новый эллемент в исходные файлы. (kpok.cpp) + +3)Далее нужно создать в одной папке с проектом, папку "dependencies" и закинуть в неё содерживомое скаченной библиотеки json. + +4)Закинуть прикреплённый файл format.json в в папку с проектом. + +5)Вставить + From 4111b3274fb2e7e19408d3d213395a9e4b54d5e9 Mon Sep 17 00:00:00 2001 From: Wammero <107371364+Wammero@users.noreply.github.com> Date: Sun, 28 Apr 2024 01:05:42 +0300 Subject: [PATCH 2/3] Create decision.cpp --- decision.cpp | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 decision.cpp diff --git a/decision.cpp b/decision.cpp new file mode 100644 index 00000000..41fa9b31 --- /dev/null +++ b/decision.cpp @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "dependencies/include/nlohmann/json.hpp" + +struct item { // структура для хранения купленных предметов +private: + std::string id; + std::string name; + + struct category_class { // структура для хранения к какой категории относится предмет + private: + std::string id; + std::string name; + public: + category_class() = delete; // запрещён конструктор по умолчанию + category_class(const std::string& category_id, const std::string& category_name) : id(category_id), name(category_name) {}; // конструктор, для создания категории + + const std::string& get_category_name() { // функция возвращающая название категории + return name; + } + }; +public: + category_class category; + item() = delete; // запрещён конструктор по умолчанию + item(const std::string& item_id, const std::string& item_name, const std::string& category_id, const std::string& category_name) : id(item_id), name(item_name), category(category_id, category_name) {}; // конструктор, который создаёт предметы, которые мы покупаем +}; + + +struct date_time { // струкрура, которая хранит время покупки +private: + int year; + int month; + int day; + int hour; + int minute; + double second; +public: + date_time() = delete; // запрещён конструктор по умолчанию + date_time(const int year = 0, const int month = 0, const int day = 0, const int hour = 0, const int minute = 0, const double second = 0) : year(year), month(month), day(day), hour(hour), minute(minute), second(second) {}; // конструктор, для установки времени + + bool operator < (const date_time& b) const { // реалезация оператора (<) для реализации сортировки и бинарного поиска + return std::tie(year, month, day) < std::tie(b.year, b.month, b.day); + } + + bool operator > (const date_time& b) const { // реализация оператор (>) + return b < *this; + } +}; + +date_time set_time(const std::string& time) { // функция, которая отвечает за разбиение строки времени на токены и дальнейшее хранение + std::vector tokens; + int i = 0, j = 0; + for (i, j; i < time.size(); ++i) { + if (time[i] == '-' || time[i] == ':' || time[i] == 'T') { + tokens.push_back(time.substr(j, i - j)); + j = i + 1; + } + } + tokens.push_back(time.substr(j, i - j)); + return date_time(std::stoi(tokens[0]), std::stoi(tokens[1]), std::stoi(tokens[2]), std::stoi(tokens[3]), std::stoi(tokens[4]), std::stod(tokens[5])); +} + + +struct bought { // структура, которая хранит время покупки и список покупок в этот момент +private: + date_time time; + std::vector items; +public: + bought() = delete; // запрещён конструктор по умолчанию + bought(const std::string& time) : time(set_time(time)) {}; // конструктор установки времени + + void push(const item& item) { // функция заполнения вектора покупок - покупками + items.push_back(item); + } + + date_time& gettime() { // функция, которая возвращает время + return time; + } + + std::vector& bought_items() { // функция, которая возвращает вектор покупок + return items; + } + + bool operator<(const bought& b) const { // оператор (<) для сортировки + return this->time < b.time; + } + + bool operator>(const bought& b) const { // оператор (>) + return b.time < this->time; + } +}; + +std::set find(std::vector& all_boughts, date_time& left_date, date_time& right_date) { // функция для поиска самых популярных категорий в определённом промежутки времени с left_date по right_date включительно + int left = -1, right = all_boughts.size(); + while (right - left > 1) { // поиск левой границы, right + int mid = left + (right - left) / 2; + + if (all_boughts[mid].gettime() < left_date) { + left = mid; + } + else { + right = mid; + } + } + int left2 = -1, right2 = all_boughts.size(); + while (right2 - left2 > 1) { // поиск правой границы, left2 + int mid = left2 + (right2 - left2) / 2; + + if (all_boughts[mid].gettime() > right_date) { + right2 = mid; + } + else { + left2 = mid; + } + } + if (left2 == -1 || right == all_boughts.size()) { // если нет ни одной подходящей покупки + std::cout << "No result\n"; + std::set set; + return set; + } + std::unordered_map categories_counter; // map для подсчёта количества категорий + int max = 0; + for (int i = right; i <= left2; ++i) { + for (auto items : all_boughts[i].bought_items()) { + max = std::max(++categories_counter[items.category.get_category_name()], max); + + } + } + std::set ans; + for (int i = right; i <= left2; ++i) { // заполнения ans подходящими категориями + for (auto items : all_boughts[i].bought_items()) { + if (categories_counter[items.category.get_category_name()] == max) ans.insert(items.category.get_category_name()); + } + } + return ans; +} + +void print(std::set& s) { // функция вывода + nlohmann::json report; + report["categories"] = s; + /*std::ofstream file("report.json"); // Создание файла report.json с ответом + if (file.is_open()) { + file << report; + file.close(); + }*/ + std::cout << report.dump(); +} + +int main() { + std::locale::global(std::locale("ru_RU.UTF-8")); + + std::vector all_boughts; // вектор покупок + + nlohmann::json objJson; // объявляем переменную objJson типа nlohmann::json для хранения JSON данных + std::fstream fileInput; // объявляем переменную fileInput типа std::fstream для работы с файлом + fileInput.open("format.json"); // открываем файл с именем "format.json" для чтения + fileInput >> objJson; // считываем содержимое файла в переменную objJson с помощью оператора >> + fileInput.close(); // закрываем файл после чтения + for (auto boughts : objJson) { // заполнение all_boughts + bought buy(boughts["ordered_at"]); + for (auto items : boughts["items"]) { + item item(items["id"], items["name"], items["category"]["id"], items["category"]["name"]); + buy.push(item); + } + all_boughts.push_back(buy); + } + std::sort(all_boughts.begin(), all_boughts.end()); // сортировка для бинарного поиска, сделанно, если будет множественные запросы + date_time left_date(2023, 12, 1); // левая дата + date_time right_date(2023, 12, 31); // правая дата + std::set ans; + ans = find(all_boughts, left_date, right_date); // вызов функции find + print(ans); // вывод +} From 9ebcc67ec203b7e70d0cc5535c88c9205ed5ff41 Mon Sep 17 00:00:00 2001 From: Wammero <107371364+Wammero@users.noreply.github.com> Date: Sun, 28 Apr 2024 01:08:43 +0300 Subject: [PATCH 3/3] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db6aac87..094fce09 100644 --- a/README.md +++ b/README.md @@ -73,5 +73,7 @@ telegram - @wammero 4)Закинуть прикреплённый файл format.json в в папку с проектом. -5)Вставить +5)Вставить содержимое прикреплённого файла decision.cpp в наш файл kpok.cpp + +6)Запустить проект